异常处理器是拦截器的一种实现方式。
@ExceptionHandler类级别的异常
@ExceptionHandler是类级别的注解,例如要处理一个controller里的异常:
@ExceptionHandler({Exception.class}) // 所有异常都由这个方法处理
public String handle(Exception e){
System.out.println(e.toString());
return "500";
}
@RequestMapping(value="/findOne")
public String findOne(@RequestParam(name="id") String id){
System.out.println(0/0); //zero异常
return "404";
}
访问地址触发异常:: http://localhost:8080/findOne?id=1
全局处理异常
每个controller都写一个@ExceptionHandler太累了。
用@ControllerAdvice 可以将所有controller抛出的异常都拦截到,非常方便,如代码:
@ControllerAdvice
public class GlobalExceptionHandler {
public GlobalExceptionHandler() {
}
@ExceptionHandler({NoHandlerFoundException.class}) // 未
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseEntity handle404Error(HttpServletRequest req, HttpServletResponse rsp, Exception e) throws Exception {
System.out.println("handle404Error");
return new ResponseEntity("handle404Error",null, HttpStatus.NOT_FOUND);
}
@ExceptionHandler({Exception.class})
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseEntity handle500Error(HttpServletRequest req, HttpServletResponse rsp, Exception e) throws Exception {
System.out.println("handle500Error");
return new ResponseEntity("handle500Error",null, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler({NullPointerException.class})
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseEntity handleNullException(HttpServletRequest req, HttpServletResponse rsp, NullPointerException e) throws Exception {
System.out.println("handleNullException");
return new ResponseEntity("handleNullException",null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
查看全局异常处理在哪里
项目中的RuntimeException都被拦截,返回json格式的result,想看下处理逻辑到底在哪里。
搜索 ExceptionHandler,只找到一堆日志
搜索 ControllerAdvice 还是没有找到
会在哪里呢? 范围已经选的是all places,而且没有使用*.java过滤器。
后来终于找到是在压缩好的包里, 就叫做 GlobalExceptionHandler,这需要对项目熟悉才能找到。
回头看了下 搜索 ExceptionHandler 的日志,里面也出现了。 所以不要放过任何一个点。
多个@ControllerAdvice的顺序
可以通过@Order 和@Primary 来设置,需要实测一下。
如何查看所有的异常拦截器
启动actuator之后也不行,因为虽然可以看到所有的bean,但是只能找到bean的名字,并不能知道bean是否有异常拦截的功能。
求解。