在ajax请求中,使用validateAction校验参数,这个action中遇到校验出错使用addActionError,但这时候前端请求遇到校验出错的时候就跳到了500页面(服务器错误),拿不到错误信息.经过一步步debug,发现在走workfolw拦截器之后报了一个异常:No result defined for action and result input,原来是在这个拦截器中检测到有actionError,然后就返回了input,
if (action instanceof ValidationAware) {
ValidationAware validationAwareAction = (ValidationAware) action;
if (validationAwareAction.hasErrors()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Errors on action " + validationAwareAction + ", returning result name 'input'");
}
String resultName = inputResultName;
if (action instanceof ValidationWorkflowAware) {
resultName = ((ValidationWorkflowAware) action).getInputResultName();
}
InputConfig annotation = action.getClass().getMethod(invocation.getProxy().getMethod(), EMPTY_CLASS_ARRAY).getAnnotation(InputConfig.class);
if (annotation != null) {
if (!annotation.methodName().equals("")) {
Method method = action.getClass().getMethod(annotation.methodName());
resultName = (String) method.invoke(action);
} else {
resultName = annotation.resultName();
}
}
return resultName;
}
}
但是这个action对应的struts配置是:
<result type="json"> <param name="root">ajaxResult</param> </result>
只有一个result配置,应该是默认的success才会使用(因为input的返回就抛错了),没有配置input的跳转,然后就会抛出No result defined for action and result input异常,如果这样配置就可以了.但是太丑陋了,拿不到actionError中的错误信息.只能再在ajaxResult中填写一遍,不推荐这样解决:
<result name="success" type="json" > <param name="root">ajaxResult</param> </result> <result name="input" type="json"> <param name="root">ajaxResult</param> </result>
还有个疑问,这个异常抛出来为什么不会被<global-exception-mappings>捕捉到呢?
<global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="exception"/> </global-exception-mappings>google:
someone写道
<exception-mapping>与<global-exception-mapping>
这两个标签都是用来配置发生异常时对应的视图信息的,一个是Action范围的,一个是包范围的,当同一类型异常在两个范围都被配置时,Action范围的优先级要高于包范围的优先级.
这两个标签都是用来配置发生异常时对应的视图信息的,一个是Action范围的,一个是包范围的,当同一类型异常在两个范围都被配置时,Action范围的优先级要高于包范围的优先级.
原来所谓global只是package范围内的!!!找不到input抛出的异常相当于struts的异常.global-exception捕获不到.struts自己处理了,跳到500页面.
解决方案:
配置拦截器,删掉default拦截器,然后在自己的拦截器堆栈中加上一些自己需要的default中的拦截器,再在validation拦截器和workflow拦截器之间加上一个拦截器:jsonValidationInterceptor.主要内容:
if (action instanceof ValidationAware) {
ValidationAware validationAware = (ValidationAware) action;
if (validationAware.hasErrors()) {
response.setCharacterEncoding("UTF-8");
response.getWriter().print(buildResponse(validationAware));//自己组装错误信息
response.setContentType("application/json");
return Action.NONE;
}
}
struts.xml配置:
<interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> <interceptor-ref name="jsonValidationInterceptor"/> <interceptor-ref name="workflow"/>
然后work happily...