struts2 18拦截器详解(十七)
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。
下一篇: JSP网页防止sql注入攻击