异常处理器
什么是异常处理器
在Spring MVC中,提供了一个全局异常处理器,用于对系统中出现的异常进行统一的处理。在一般的系统中,DAO,Service及Controller层都出现的异常都以“throws Exception”的形式向上层抛出,最后都会由Spring MVC的前端控制器DispatcherServlet统一由全局异常处理器进行异常处理。
对于预期的异常,通常要定义一个自定义异常类,该类用于在发生异常后,存储异常信息,最终交给全局异常处理器处理该异常。
异常处理器执行流程
实现方式
SpringMVC提供了异常处理器多种方式
方式一:实现HandlerExceptionResolver
方式二:通知类
使用@ControllerAdvice对Controller增强
使用@ExceptionHandler捕获异常
基本功能
需求
访问 /demo04/item.action?id=1
id =1 系统异常
id =2 自定义异常
id =3 正常
步骤
编写自定义异常
编写Controller 接受一个参数 (系统异常 自定义异常 正常)
编写访问连接
实现
- 编写自定义异常 继承RuntimeException 重写构造
public class CustomExcption extends RuntimeException { public CustomExcption() { } public CustomExcption(String message) { super(message); } public CustomExcption(String message, Throwable cause) { super(message, cause); } public CustomExcption(Throwable cause) { super(cause); } public CustomExcption(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
2.编写Controller 接受参数
@Controller @RequestMapping("/demo04") public class Demo04ItemController { @RequestMapping("/item") public String item(Integer id ) { if(id == 1) { // 系统异常 int i = 1 / 0; } else if( id == 2 ) { // 自定义 throw new CustomExcption("自定义异常信息"); } //正常 return "forward:/index.jsp"; } }
3.编写访问连接
<a href="${pageContext.request.contextPath}/demo04/item.action?id=1">异常处理 id =1 系统异常</a> <br/> <a href="${pageContext.request.contextPath}/demo04/item.action?id=2">异常处理 id =2 自定义异常 </a> <br/> <a href="${pageContext.request.contextPath}/demo04/item.action?id=3">异常处理正常</a> <br/>
方式一:实现接口
编写HandlerExceptionResolver接口的实现类CustomExceptionResolver
实现方法resolverException()
并根据参数Exception e对异常进行处理:自定义异常 系统异常
@Component public class CustomExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { // 1 统一异常 CustomExcption customExcption = null; if(e instanceof CustomExcption) { customExcption = (CustomExcption) e; } else { customExcption = new CustomExcption("系统繁忙,请稍后重试!"); } // 2 错误信息返回 ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message" ,customExcption.getMessage()); modelAndView.setViewName("forward:/error.jsp"); return modelAndView; } }
方式二:通知类
编写GlobalExceptionResolver类 用于处理所有异常
在类上添加@Controller的增强器@ControllerAdvice
在对应的方法上添加@ExceptionHandler来捕获异常
@ControllerAdvice public class GlobalExceptionResolver { /** * 自定义异常处理器 * @param ec * @param model * @return */ @ExceptionHandler(CustomExcption.class) public String custom(CustomExcption ec, Model model) { model.addAttribute("message", ec.getMessage() + "Global"); return "forward:/error.jsp"; } /** * 其他异常处理器 * @param e * @param model * @return */ @ExceptionHandler(Exception.class) public String other(Exception e, Model model) { model.addAttribute("message", "系统繁忙,请稍后重试!" + "Global"); return "forward:/error.jsp"; } }
异常信息展示页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>友好页面</title> </head> <body> ${message} </body> </html>
总结
视图解析器:
可以帮助我们快速修改视图路径 不用一个一个Controller去修改
方法返回值:
方法返回值默认是ModelAndView Model默认是request作用域 绕过视图解析器 使用请求转发 或者重定向
异常处理器:
更加友好的提示异常