程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> struts2 18攔截器詳解(十七)

struts2 18攔截器詳解(十七)

編輯:關於JSP

StrutsConversionErrorInterceptor      StrutsConversionErrorInterceptor攔截器處於defaultStack第十六的位置,是用於處理轉類型轉換錯誤的,該攔截器繼承自ConversionErrorInterceptor類其大部分功能邏輯都在ConversionErrorInterceptor中,StrutsConversionErrorInterceptor只是對其中的兩個方法進行了覆蓋,分別是getOverrideExpr與shouldAddError方法,因為ConversionErrorInterceptor類是xwrok提供的,而struts2認為這兩個方法不是那麼合理所以進行了覆蓋。所以真正執行到StrutsConversionErrorInterceptor調用的是父類ConversionErrorInterceptor的intercept方法,下面是該方法源碼:  

@Override  
public String intercept(ActionInvocation invocation) throws Exception {  
    //獲取ActionContext對象  
    ActionContext invocationContext = invocation.getInvocationContext();  
    //獲取ActionContext對象中的conversionErrors Map,所以類型轉換錯誤信息都放在該Map中  
    Map<String, Object> conversionErrors = invocationContext.getConversionErrors();  
    ValueStack stack = invocationContext.getValueStack();//獲取值棧  
  
    HashMap<Object, Object> fakie = null;  
    //迭代類型轉換錯誤  
    for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) {  
        String propertyName = entry.getKey();//轉換錯誤的請求參數名  
        Object value = entry.getValue();//轉換錯誤的請求參數值  
  
        if (shouldAddError(propertyName, value)) {//判斷是否要添加錯誤信息  
            String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);//獲取錯誤提示信息  
            //獲取當前Action  
            Object action = invocation.getAction();  
            if (action instanceof ValidationAware) {//只有Action實現了ValidationAware接口  
                ValidationAware va = (ValidationAware) action;  
                //才會將錯誤信息添加到FieldError集合中,因為沒有實現ValidationAware接口根本就沒有addFieldError方法  
                va.addFieldError(propertyName, message);  
            }  
  
            if (fakie == null) {  
                fakie = new HashMap<Object, Object>();  
            }  
            //將錯誤值添加到fakieMap中(fakie意思是:假貨,騙子)  
            fakie.put(propertyName, getOverrideExpr(invocation, value));  
        }  
    }  
    //如果fakie有值  
    if (fakie != null) {  
        // 將fakie Map放到ActionContext中  
        stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie);  
        //注冊一個PreResultListener監聽器  
        invocation.addPreResultListener(new PreResultListener() {  
            public void beforeResult(ActionInvocation invocation, String resultCode) {  
                Map<Object, Object> fakie = (Map<Object, Object>) invocation.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE);  
  
                if (fakie != null) {  
                    invocation.getStack().setExprOverrides(fakie);  
                }  
            }  
        });  
    }  
    return invocation.invoke();//調用下一個攔截器  
}  

 

       這裡只有Action實現了ValidationAware接口才能將類型轉換錯誤信息添加到FieldError中,提供給最後一個攔載器:DefaultWorkflowInterceptor使用,而且有類型轉換錯誤還會注冊一個PreResultListener監聽器,該監聽器會在Action與攔截器執行完畢之後,Result執行之前執行,這個監聽器就是把存儲在ActionContext中的fakie Map取出來調用ValueStack的setExprOverrides方法設置進行值棧中,當你再頁面中通過OGNL表達獲取該類型轉換出錯的參數時返回的是參數原來的值。例如有一請求參數path?age=xxx,而在Action中是用int類型去接收的,這樣就會報轉換錯誤,當你在頁面中用OGNL獲取age值(<s:property value="age"/>)時返回的是xxx而不是0。  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved