1.介绍
@ControllerAdvice是SpringMVC中的一个增强Controller,使用这个 Controller ,可以实现三个方面的功能:
- 全局异常处理
- 全局数据绑定
- 全局数据预处理
2.使用
2.1.全局异常处理
在方法上使用@ExceptionHandler注解,就能全局处理注解内的异常。
@ControllerAdvice
public class MyGlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(MyException.class)
public JsonResult<String> handleException(Exception e) {
return JsonResult.failed(e.getMessage());
}
}
2.2.全局数据绑定
在方法上使用@ModelAttribute注解,该方法就会在此Controller中第一个执行。
@ControllerAdvice
public class MyGlobalExceptionHandler {
@ModelAttribute
public void initData(HttpServletRequest request) {
request.setAttribute("hello", "world");
}
}
在普通Controller中,就可以取到这个属性。
@Controller
@RequestMapping("/")
public class MyController {
public JsonResult<String> hello(HttpServletRequest request){
String data = request.getAttribute("hello");
return JsonResult.success(data);
}
}
2.3.全局数据预处理
假设有两个实体类Book和Author
@Data
public class Book {
private String name;
private Long price;
}
@Data
public class Author {
private String name;
private Integer age;
}
在Controller中直接绑定实体,就会出现问题,由于Book和Author中都有属性name,请求参数中的name参数就无法区分到底绑定哪个实体。
@PostMapping("/book")
public void addBook(Book book, Author author) {
// save
}
这时,可以用@ModelAttribute注解给接口中的变量取别名。
@PostMapping("/book")
public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) {
// save
}
在@ControllerAdvice 标记的类中,使用@InitBinder注解对数据进行绑定,注解中的值和@ModelAttribute中的别名对应。
@InitBinder("b")
public void b(WebDataBinder binder) {
binder.setFieldDefaultPrefix("b.");
}
@InitBinder("a")
public void a(WebDataBinder binder) {
binder.setFieldDefaultPrefix("a.");
}
前端请求时需要将请求参数加上前缀,如b.name, b.price, a.name, a.age
,数据就可以被正确绑定。