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。
爱的姑娘是百合