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

来源:互联网 发布:剑网三炮哥捏脸数据 编辑:程序博客网 时间:2024/06/05 02:01

在使用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 extendsSimpleMappingExceptionResolver {@Overrideprotected 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 blocke.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
原创粉丝点击