Spring Boot 提供了全局异常配置,我们可以使用 @ControllerAdvice 注解来标记处理异常的类,在方法上使用 @ExceptionHandler(value=XXXXException.class) 注解来标记该方法处理什么异常。
@ControllerAdvice public class CustomExtHandler { private static final Logger LOG = LoggerFactory.getLogger(CustomExtHandler.class); //捕获全局异常,处理所有不可知的异常 @ExceptionHandler(value=Exception.class) @ResponseBody Object handleException(Exception e,HttpServletRequest request){ LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage()); Map<String, Object> map = new HashMap<>(); map.put("code", 100); map.put("msg", e.getMessage()); map.put("url", request.getRequestURL()); return map; } }
注意:如果不加 @ResponseBody 注解,则返回一个视图,如果找不到视图,则报 404 错误,所以我们这里加上 @ResponseBody 是为了返回 Json 数据。当然,如果使用 @RestControllerAdvice 则不用加 @ResponseBody。
如果发生异常想返回自定义页面,那么就需要使用模板,需要引入 thymeleaf 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
这里我们顺带演示怎样自定义异常。
自定义异常类如下所示:
public class MyException extends RuntimeException { public MyException(String code, String msg) { this.code = code; this.msg = msg; } private String code; private String msg; //省略getter、setter方法 }
异常处理类
@RestControllerAdvice public class CustomExtHandler { //功能描述:处理自定义异常 @ExceptionHandler(value=MyException.class) Object handleMyException(MyException e,HttpServletRequest request){ //进行页面跳转 ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error.html"); modelAndView.addObject("msg", e.getMessage()); return modelAndView; //返回json数据,由前端去判断加载什么页面 //Map<String, Object> map = new HashMap<>(); //map.put("code", e.getCode()); //map.put("msg", e.getMsg()); //map.put("url", request.getRequestURL()); //return map; } }
resource 目录下新建 templates 文件夹,并新建 error.html
测试一下,主动抛出我们自定义的异常
@RequestMapping("/api/v1/myext") public Object myexc(){ throw new MyException("499", "my ext异常"); }
效果如下: