@ControllerAdvice / @RestControllerAdvice 有三方面的功能
- 全局异常处理
- 全局数据绑定
- 全局数据预处理
全局异常处理
使用@ExceptionHandler 注解用来指明处理异常的类型
@RestControllerAdvice
public class MyGlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public String ExceptionHandler(Exception e){
System.out.println("所有异常拦截处理" + e.getMessage());
return e.getMessage();
}
@ExceptionHandler(NullPointerException.class)
public String NullPointerExceptionHandler(NullPointerException e){
System.out.println("空指针异常拦截处理" + e.getMessage());
return e.getMessage();
}
}
注意:既指定了Exception.class拦截所有异常,又指定了具体的异常拦截时,比如NullPointerException.class,当发生空指针异常时,只会进入NullPointerException.class中
全局数据绑定
1. 使用@ModelAttribute注解标记该方法的返回数据是一个全局数据,name属性用来指定数据的key
@RestControllerAdvice
public class MyGlobalData {
@ModelAttribute(name = "gUserData")
public Map<String, Object> initUserData() {
Map<String, Object> userMap = new HashMap<>();
userMap.put("name", "admin");
userMap.put("age", 23);
userMap.put("address", "中国");
return userMap;
}
}
2. 在项目的任何Controller中都可以使用Model对象直接获取该数据
@RestController
public class TestController {
@GetMapping("test")
public void test(Model model){
// 1. model.asMap()
Map<String, Object> asMap = model.asMap();
// 2. 通过指定的name值来获取数据,未指定则默认为map
Map<String, Object> info = (Map<String, Object>) asMap.get("gUserData");
Set<String> keys = info.keySet();
for (String key : keys) {
System.out.println(key + "----" + info.get(key));
}
}
}
数据预处理
示例:现在有Book类和Author类两个实体,均有name属性
@Getter
@Setter
@ToString
public class Book {
private String name;
private String price;
}
@Getter
@Setter
@ToString
public class Author {
private String name;
private String age;
}
接收请求的方法:
@PostMapping("addBook")
public void addBook(Book book, Author author){
System.out.println("book = " + book);
System.out.println("author = " + author);
}
当传参中有两个name属性时,默认会将相同名称的字段合并
输出结果为:
book = Book(name=三国演义,罗贯中, price=36)
author = Author(name=三国演义,罗贯中, age=88)
把代码做下调整,接收请求参数时,使用@ModelAttribute指定参数的映射:
@PostMapping("addBook")
public void addBook(@ModelAttribute("book") Book book, @ModelAttribute("author") Author author){
System.out.println("book = " + book);
System.out.println("author = " + author);
}
对请求参数进行预处理:
@RestControllerAdvice
public class MyGlobalPreData {
/**
* 通过处理器在 book 对象添加前缀 b.
* @param binder
*/
@InitBinder("book")
public void bookBinder(WebDataBinder binder){
binder.setFieldDefaultPrefix("b.");
}
/**
* 通过处理器在 author 对象添加前缀 a.
* @param binder
*/
@InitBinder("author")
public void authorBinder(WebDataBinder binder){
binder.setFieldDefaultPrefix("a.");
}
}
请求时,属性加上对应的前缀
输出结果:
book = Book(name=三国演义, price=36)
author = Author(name=罗贯中, age=88)