使用Spring实现异常统一处理【二】

在使用Spring实现异常统一处理【一】中,已给出一个关于返回json的异常处理方案,但此方案是根据http headeraccept字段判断请求是否为json,如果我们accept字段不设置为“application/json”,则无法对json请求进行有效的异常统一处理。

        在http://blog.csdn.net/m13321169565/article/details/7641978文章中,通过判断请求处理方法是否存在@ResponseBody注解,对Json等通过HttpMessageConverter处理的请求,进行区别异常处理。

        结合以上经验,自定义一异常处理类,继承于SimpleMappingExceptionResolver,具体配置如下:

        1、定义Java类

public class CustomSimpleMappingExceptionResolver extends
		SimpleMappingExceptionResolver {

	@Override
	protected ModelAndView doResolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception exception) {

		if (handler == null) {
			return null;
		}
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();

		if (method == null) {
			return null;
		}
		Class<?> methodReturnType=method.getReturnType();
		System.out.println("return type:"+methodReturnType.getName());
		System.out.println("exception:"+exception.getCause()+","+exception.getLocalizedMessage());
		ResponseBody responseBody = AnnotationUtils.findAnnotation(method,
				ResponseBody.class);
		if (methodReturnType.getName().equals("void")||responseBody != null) {
			PrintWriter writer;
			try {
				String returnStr="{error:'"+exception.getMessage()+"'}";
				writer = response.getWriter();
				writer.write(returnStr);
				writer.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();

			}

		} else {
			String viewName = super.determineViewName(exception, request);
			System.out.println("viewName:"+viewName);
			
			if (viewName != null) {// JSP格式返回

				Integer statusCode = super.determineStatusCode(request,
						viewName);
				if (statusCode != null) {
					super.applyStatusCodeIfPossible(request, response,
							statusCode);
				}
				return super.getModelAndView(viewName, exception, request);
			}
		}
		return null;

	}// doResolveException

}



        2、springmvc-servlet.xml(DispatcherServlet名称为springmvc)添加定义:

<bean id="exceptionResolver"
	class="com.winssage.exception.CustomSimpleMappingExceptionResolver">
	<property name="defaultErrorView" value="/exception/errorpage" />
	<!--  定义异常处理页面用来获取异常信息的变量名,如果不添加exceptionAttribute属性,则默认为exception-->
	<property name="exceptionAttribute" value="exception" />
	<property name="exceptionMappings">
		<props>
			<!--不设置将根据defaultErrorView-->
			<prop key="java.lang.exception">/exception/errorpage</prop>
			<prop key="java.lang.RuntimeException">/exception/errorpage</prop>
		</props>
	</property>
	<property name="order" value="0"/>
</bean>



        3、errorpage.jsp定义

<%@page contentType="text/html" pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
	<h1>Hello World!error!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ${exception}
	</h1>	
</body>
</html>

        问题总结:

        1、在调试过程中,发现SimpleMappingExceptionResolver对某些异常捕捉不到,比如Spring MVC 的@RequestParam的类型映射不匹配,又比如在返回json进行httpMessageConverter处理时的异常,都捕捉不到。原因为:在xml定义中exceptionMappings漏定义了 <prop key="java.lang.RuntimeException">/exception/errorpage</prop>。 

        2、添加上配置 <prop key="java.lang.RuntimeException">/exception/errorpage</prop>后,对json进行HttpMessageConverter转换时,又报java.lang.IllegalStateException: STREAM错误,目前该问题还未解决。

        3、所以用 SimpleMappingExceptionResolver希望对系统所有异常进行统一处理,仍存在问题,只能配合DefaultMappingExceptionResolver一起使用。

         DefaultMappingExceptionResolver的配置:在Web.xml中添加:

<error-page>
	<error-code>500</error-code>
	<location>/error/show.do</location>
</error-page>
<error-page>
	<error-code>400</error-code>
	<location>/errorpage.jsp</location>
</error-page>
               注:error-page可以指向jsp也可指向一个http request

              DefaultMappingExceptionResolver方式的errorpage.jsp定义:

<%@page contentType="text/html" pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<%
	response.setStatus(200); // 200 = HttpServletResponse.SC_OK
%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
	<h1>Hello World!error!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		${pageContext.exception }</h1>
</body>
</html>
            其中,<% response.setStutus(200);%>是为了解决IE的友好报错界面而设置的。  IE的友好报错界面真讨厌

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值