天天看點

struts2 18攔截器詳解(十九) --- DefaultWorkflowInterceptor

DefaultWorkflowInterceptor

   DefaultWorkflowInterceptor攔截器處于defaultStack第十八的位置,為defaultStack攔截器棧中的最後一個攔截器,其主要功能是判斷目前Action的執行過程有無錯誤,包含ActionError與FieldError兩種,例如在請求參數類型轉換出錯後就會添加FieldError。如果執行過程中有錯誤則會跳轉到指定的Result(預設為input)。該攔截器繼承自MethodFilterInterceptor類,是以也可以配置哪些方法要應用上該攔截器,哪些方法不要應用上該攔截器,下面是該攔截器在defaultStack中的配置:

<interceptor-ref name="workflow">
    <param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
           

也就是說明對于Action的input,back,cancel,browse方法是不會應用上該攔截器的。

下面是該攔截器的doIntercept方法源碼:

@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
    Object action = invocation.getAction();//擷取目前執行的Action對象
	//判斷Action是否實作了ValidationAware,繼承自ActionSupport類的Action即實作了該接口
    if (action instanceof ValidationAware) {
        ValidationAware validationAwareAction = (ValidationAware) action;//強轉
		//判斷Action執行過程中有無錯誤
        if (validationAwareAction.hasErrors()) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Errors on action " + validationAwareAction + ", returning result name 'input'");
            }
			//inputResultName屬性值為"input",這是在該攔截器寫死的
            String resultName = inputResultName;
			//Action有無實作ValidationWorkflowAware接口
            if (action instanceof ValidationWorkflowAware) {
            	//如果實作了則由Aciton的getInputResultName()方法決定resultName的值
                resultName = ((ValidationWorkflowAware) action).getInputResultName();
            }
			//判斷目前Action要執行的方法上是否标有InputConfig注解
            InputConfig annotation = action.getClass().getMethod(invocation.getProxy().getMethod(), EMPTY_CLASS_ARRAY).getAnnotation(InputConfig.class);
            if (annotation != null) {
                if (!annotation.methodName().equals("")) {//如果InputConfig注解的methodName屬性長度不為0
                    Method method = action.getClass().getMethod(annotation.methodName());//擷取Action中由InputConfig注解的methodName屬性指定的方法
                    resultName = (String) method.invoke(action);//則resultName由該方法的傳回值決定
                } else {//否則由InputConfig注解的resultName屬性值決定
                    resultName = annotation.resultName();
                }
            }
			//将resultName值傳回
            return resultName;
        }
    }
	//如果Action沒有實作ValidationAware接口則直接執行Action中的方法
    return invocation.invoke();
}
           

   學過struts2的肯定知道,如果Action執行的過程出了錯(當然前提是添加到了ActionError或FieldError中)就會轉向一個名為input的Result,其實就是通過該攔截器實作的,這也是為什麼這個Result的名字為input的原因。當然這個Result的名字是可以改的,方式就有很多了:

1.給該攔截器在配置檔案上傳遞一個名為inputResultName的參數,其值由自己決定

2.讓Aciton實作ValidationWorkflowAware接口,Result名字就會由ValidationWorkflowAware接口中聲明的getInputResultName方法決定

3.在Action中執行的方法上面添加InputConfig注解,該注解有兩個屬性:methodName-->用于指定目前Action中的一個方法名稱,用該方法的傳回值作為Result名字;resultName-->直接指定Result名字。

  最後調用invocation.invoke();執行Action中的方法,因為在defaultStack中這已經是最後一個攔截器,是以調用的是Action中的方法了......

繼續閱讀