欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

struts2 18拦截器详解(十七)

程序员文章站 2022-12-01 10:28:57
strutsconversionerrorinterceptor      strutsconversionerrorinterceptor拦截器处于defaultst...
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。