struts2 ajax请求使用json配置时出现500页面问题分析

在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范围的优先级要高于包范围的优先级.

 原来所谓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...
 

相关推荐