在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一, 也实现了异常信息的统一处理和维护 。
springmvc的异常处理思路
系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
Spring/SpringMVC常见的统一异常处方式:
1) 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver,处理器实现HandlerExceptionResolver 接口,全局异常处理器需要实现该接口
SimpleMappingExceptionResolver,就是通过简单的映射关系来决定由哪个视图,来处理当前的错误信息。SimpleMappingExceptionResolver提供通过异常类型exceptionMappings,来进行异常与视图之间的映射关系,提供在发生异常时,通过statusCodes来映射异常返回的视图名称和对应的HttpServletResponse的返回码。而且可以通过defaultErrorView和defaultErrorCode来指定默认值,defaultErrorView表示当没有在exceptionMappings里面找到对应的异常类型时,就返回defaultErrorView定义的视图,defaultErrorCode表示在发生异常时,当没有在视图与返回码的映射关系statusCodes里面找到对应的映射时,默认返回的返回码。
在使用SimpleMappingExceptionResolver时,当发生异常的时候,SimpleMappingExceptionResolver将会把当前的异常对象放到自身属性exceptionAttribute中,当没有指定exceptionAttribute时,exceptionAttribute就是用默认值exception
首先得在webApplicationContext.xml文件中配置该处理器:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--默认的异常处理页面--> <property name="defaultErrorView" value="user/error"/> //错误页面的路径:如果配置modelView.addView("/WEB-INF/views"),就是相对路径 <!--异常处理页面用来获取异常信息的变量名,默认为exception--> <property name="exceptionAttribute" value="ex"/> <!--需要特殊处理的异常信息--> <property name="exceptionMappings"> <props> <prop key="com.smart.exception.CustomException">user/custom_error</prop> </props> </property>
<property name="statusCodes"> <!-- 定义在发生异常时视图跟返回码的对应关系 -->
<props>
<prop key="number">500</prop> <!-- 表示在发生NumberFormatException时返回视图number,
然后这里定义发生异常时视图number对应的HttpServletResponse的返回码是500 -->
<prop key="null">503</prop>
</props>
</property>
</bean>
最重要的是要配置特殊处理的异常,自定义一个CustomException
package com.smart.exception; /** * 自定义异常 * **/ public class CustomException extends Exception{ private String message; public CustomException(String message){ super(message); this.message=message; } @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
2) 实现Spring的异常处理接口HandlerExceptionResolver 自定义全局异常处理器
全局异常处理器处理思路
- 解析出异常类型
- 如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示
- 如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型
springmvc提供一个HandlerExceptionResolver接口,自定义全局异常处理器必须要实现这个接口
public class CustomExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); if(ex instanceof CustomException){ CustomException exception=(CustomException)ex; modelAndView.addObject("message",exception.getMessage()); modelAndView.setViewName("user/custom_error"); return modelAndView; }else{ modelAndView.addObject("message",ex.getMessage()); modelAndView.setViewName("user/error"); return modelAndView; } } }
在springmvc.xml中配置这个自定义的异常处理器:
<!-- 自定义的全局异常处理器 只要实现HandlerExceptionResolver接口就是全局异常处理器--> <bean class="com.smart.CustomExceptionResolver"></bean>
3) 使用@ExceptionHandler注解实现异常处理
处理局部异常(Controller内)
@ExceptionHandler public ModelAndView exceptionHandler(Exception ex){ ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex); System.out.println("in testExceptionHandler"); return mv; } @RequestMapping("/error") public String error(){ int i = 5/0; return "hello"; }
4) 定义一个类并配上注解@ControllerAdvice。然后再该类中定义处理异常的方法并使用注解@ExceptionHandler
处理全局异常(所有Controller)
//全局异常处理,捕获所有Controller中抛出的异常
@ControllerAdvice public class testControllerAdvice {
//自定义异常 @ExceptionHandler(CustomException.class) public ModelAndView exceptionHandler(Exception ex){ ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex); System.out.println("in testControllerAdvice"); return mv; }
@ExceptionHandler(Exception.class)
@ResponseBody
public Object exceptionHandler(Exception e){
,,,,
} }
参考:
https://blog.csdn.net/eson_15/article/details/51731567