Spring MVC 全局的异常处理

原文: http://my.oschina.net/u/1757031/blog/509272
Spring异常处理配置 http://panyongzheng.iteye.com/blog/2208146
spring基于注解的全局异常处理方式 http://panyongzheng.iteye.com/blog/2067110
使用Spring MVC统一异常处理实战 http://panyongzheng.iteye.com/blog/2213655
怎么在Spring Controller里面返回404  http://jaskey.github.io/blog/2014/09/27/how-to-return-404-in-spring-controller/
java的异常处理-注解方式 http://my.oschina.net/wnjustdoit/blog/603428



1、使用SimpleMappingExceptionResolver实现异常处理

  在Spring的配置文件applicationContext.xml中增加以下内容:
<!-- 系统错误转发配置[并记录错误日志]   -->  
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
<property name="defaultErrorView" value="error"></property>   <!-- 默认为500,系统错误(error.jsp)  -->  
<property name="defaultStatusCode" value="500"></property>  
<property name="statusCodes"><!-- 配置多个statusCode -->  
  <props>      
      <prop key="error">500</prop>  <!-- error.jsp -->  
      <prop key="error1">404</prop>    <!-- error1.jsp -->  
  </props>      
</property>      
<property name="exceptionMappings">  
    <props>  
        <!-- 这里你可以根据需要定义N多个错误异常转发 -->  
        <prop key="java.sql.SQLException">dbError</prop> <!-- 数据库错误(dbError.jsp) -->  
        <prop key="org.springframework.web.bind.ServletRequestBindingException">bizError</prop> <!-- 参数绑定错误(如:必须参数没传递)(bizError.jsp) -->  
        <prop key="java.lang.IllegalArgumentException">bizError</prop>  <!-- 参数错误(bizError.jsp) -->  
        <prop key="org.springframework.validation.BindException">bizError</prop>  <!-- 参数类型有误(bizError.jsp) -->  
        <prop key="java.lang.Exception">unknowError</prop>  <!-- 其他错误为'未定义错误'(unknowError.jsp)  -->  
    </props>  
</property>  
</bean> 

注:使用SimpleMappingExceptionResolver进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但该方法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用。

2、 实现HandlerExceptionResolver 接口自定义异常处理器

  增加HandlerExceptionResolver 接口的实现类MyExceptionHandler,代码如下:
public class MyExceptionHandler implements HandlerExceptionResolver {  
   
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,  
            Exception ex) {  
        Map<String, Object> model = new HashMap<String, Object>();  
        model.put("ex", ex);  
           
        // 根据不同错误转向不同页面  
        if(ex instanceof BusinessException) {  
            return new ModelAndView("error-business", model);  
        }else if(ex instanceof ParameterException) {  
            return new ModelAndView("error-parameter", model);  
        } else {  
            return new ModelAndView("error", model);  
        }  
    }  
}

在Spring的配置文件applicationContext.xml中增加以下内容:
<bean id="exceptionHandler" class="cn.basttg.core.exception.MyExceptionHandler"/>

注:使用实现HandlerExceptionResolver接口的异常处理器进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。

3 、使用@ExceptionHandler注解实现异常处理

  增加BaseController类,并在类中使用@ExceptionHandler注解声明异常处理,代码如下:
public class BaseController {  
    /** 基于@ExceptionHandler异常处理 */  
    @ExceptionHandler({ RuntimeException.class })
    public String exp(HttpServletRequest request, Exception ex) {  
           
        request.setAttribute("ex", ex);  
           
        // 根据不同错误转向不同页面  
        if(ex instanceof BusinessException) {  
            return "error-business";  
        }else if(ex instanceof ParameterException) {  
            return "error-parameter";  
        } else {  
            return "error";  
        }  
    }  
}

以下代码来判断是否是ajax方式, 一个权限的异常处理
@ExceptionHandler({UnauthorizedException.class})
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ModelAndView exception(final UnauthorizedException e, final HttpServletRequest request, Writer writer) {
        logger.error("全句异常 UnauthorizedException 处理......");
        String message = "你没有访问这个页面,表格或者接口等权限";
        e.printStackTrace();
        if (!"XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"))) {
            ModelAndView view=new ModelAndView("/auth");
            view.addObject("message", message);
            return view;
        } else {
            try{
                ControllerContext context= ControllerContext.getNewControllerContext();
                context.addMessage(message);
                context.setError();
                writer.write(JSONUtil.toJSONString(context));
                writer.flush();
                writer.close();
            }catch (Exception e1){
                e1.printStackTrace();
            }finally {
                return null;
            }
        }
    }


修改代码,使所有需要异常处理的Controller都继承该类,

注:使用@ExceptionHandler注解实现异常处理,具有集成简单、有扩展性好(只需要将要异常处理的Controller类继承于BaseController即可)、不需要附加Spring配置等优点,但该方法对已有代码存在入侵性(需要修改已有代码,使相关类继承于BaseController),在异常处理时不能获取除异常以外的数据。

4、未捕获异常的处理

  修改web.xml文件,增加以下内容:
<!-- 出错页面定义 -->  
<error-page>  
    <exception-type>java.lang.Throwable</exception-type>  
    <location>/500.jsp</location>  
</error-page>  
<error-page>  
    <error-code>500</error-code>  
    <location>/500.jsp</location>  
</error-page>  
<error-page>  
    <error-code>404</error-code>  
    <location>/404.jsp</location>  
</error-page>  
   
<!-- 这里可继续增加服务器错误号的处理及对应显示的页面 -->

猜你喜欢

转载自panyongzheng.iteye.com/blog/2245104