文章目录
- Spring全局异常处理
- @ControllerAdvice和@ExceptionHandler
- 定义
- Order
Spring全局异常处理
Spring全局异常处理(一).
@ControllerAdvice和@ExceptionHandler
从源码的介绍里可以大概的总结如下:
- 一个注解了ControllerAdvice的类。可以定义@ExceptionHandler、@InitBinder、@ModelAttribute的方法。这样的类可以处理@Controller抛出来的异常
- 可以通过注解@Order、@Priority或者实现Ordered接口定义优先级
- 对于@ExceptionHandler的方法,处理异常的顺序是:优先级更高的类>异常的父类的处理方法>异常本身的处理方法
- 默认地,@ControllerAdvice的方法适用于所有的controllers.可以通过annotations、basePackageClasses、basePackages、value、assignableTypes指定相应的controllers。如果多个同时指定,只要满足其中一个即可
定义
使用@ControllerAdvice
和@ExceptionHandler
组合可以处理controller
抛出来的异常。例子实践一下。
异常处理
@ControllerAdvice
public class ControllerAdviceExample {
@ExceptionHandler(value = { ClassNotFoundException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "@ControllerAdvice & @ExceptionHandler handle exception!!!!!!!!!!!");
return resultMap;
}
}
控制器
@RestController
@RequestMapping("controllerAdvice")
public class ControllerAdviceController {
@GetMapping
public String handleException() throws Exception {
throw new ClassNotFoundException("--------handleException----------");
}
}
运行起来后访问/controllerAdvice
得到如下结果:
证明我们定义的全局异常处理起作用了。
Order
可以通过注解@link org.springframework.core.annotation.Order @Order
、@link javax.annotation.Priority @Priority
或者实现@link org.springframework.core.Ordered Ordered
接口定义优先级
我们定义两个ControllerAdvice类,分别用@Order定义优先顺序。
@Order(1)
@ControllerAdvice
// 定义优先级
@Order(1)
public class ControllerAdviceOrder1 {
@ExceptionHandler(value = { ClassNotFoundException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
return resultMap;
}
}
@Order(2)
@ControllerAdvice
// 定义优先级
@Order(2)
public class ControllerAdviceOrder2 {
@ExceptionHandler(value = { ClassNotFoundException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
return resultMap;
}
}
重新启动程序后访问/controllerAdvice
得到如下结果:
@Order
的值越小优先级越高,@Priority
的使用方法和@Order
是一样的,接下来我们看看如何实现Ordered接口定义优先级
优先级为1的实现
@ControllerAdvice
public class ControllerAdviceOrdered1 implements Ordered{
@ExceptionHandler(value = { ClassNotFoundException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
return resultMap;
}
// 实现该函数,返回优先级的数值
@Override
public int getOrder() {
return 1;
}
}
优先级为2的实现
@ControllerAdvice
public class ControllerAdviceOrdered2 implements Ordered {
@ExceptionHandler(value = { ClassNotFoundException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response,
Exception ex) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
return resultMap;
}
// 实现该函数,返回优先级的数值
@Override
public int getOrder() {
return 2;
}
}
启动程序后访问/controllerAdvice
得到如下结果:
接口Ordered
通过实现getOrder
函数实现优先级的赋值。
实现接口PriorityOrdered的类优先级低于实现了接口Ordered的类
Ordered定义优先级为1的ControllerAdvice
@ControllerAdvice
public class ControllerAdviceOrdered1 implements Ordered {
@ExceptionHandler(value = { ClassNotFoundException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response,
Exception ex) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
return resultMap;
}
// 实现该函数,返回优先级的数值
@Override
public int getOrder() {
return 1;
}
}
ControllerAdvicePriorityOrdered定义优先级为2的ControllerAdvice
@ControllerAdvice
public class ControllerAdvicePriorityOrdered implements PriorityOrdered{
@ExceptionHandler(value = { ClassNotFoundException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response,
Exception ex) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
return resultMap;
}
// 实现该函数,返回优先级的数值
@Override
public int getOrder() {
return 1;
}
}
启动程序后访问/controllerAdvice
得到如下结果:
虽然都定义了优先级为1,但是会先调用Ordered的实现。