@ControllerAdvice
就是@Controller
的增强版。@ControllerAdvice
主要用来处理全局数据, 一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder 使用。
一、全局异常处理
@ControllerAdvice
可以配合@ ExceptionHandler
对所有@Controller
标注的方法进行异常捕获和处理。
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 捕获MaxUploadSizeExceededException
* 文件上传超过最大限制
*/
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ModelAndView uploadException(MaxUploadSizeExceededException e){
ModelAndView mv = new ModelAndView();
mv.setViewName("maxUpload");
mv.addObject("message","上传文件大小超出限制!");
return mv;
}
}
返回值可以是JSON、ModelAndView、逻辑视图等。一般来说,都是返回一个ModelAndView,根据需求制定。
二、添加全局数据
配合@ModelAttribute
可以添加一个全局的key-value
数据,即是添加到@Controller
标记的方法里的参数Model
里的。
1、创建POJO类
@Data
public class Student {
/** ID */
private Long id;
/** 姓名 */
private String name;
/** 性别 */
private String sex;
/** 班级 */
protected String classGrade;
/** 入学日期 */
private Date admissionDate;
}
2、配置全局数据
@ControllerAdvice
public class GlobalConfig {
@ModelAttribute(value = "studentInfo")
public Student studentInfo(){
Student student = new Student();
student.setName("柳成荫");
student.setSex("男");
return student;
}
3、Controller层调用
@RestController
public class StudentController {
@GetMapping("/student")
public Student student(Model model){
Map<String, Object> map = model.asMap();
Student student = (Student) map.get("studentInfo");
return student;
}
4、测试结果
三、请求参数预处理
配合@InitBinder
能实现请求参数预处理,即将表单中的数据绑定到实体类上时进行一些额外处理
。
比如说,在一个form表单里,存在两个对象,这两个对象有相同的属性名,如果不进行预处理,可能会造成数据错乱。
1、form表单处理
给不同对象的属性添加前缀
<form action="/bookAndMusic" method="get">
<input type="text" name="book.name" placeholder="书名"><br>
<input type="text" name="book.author" placeholder="书作者"><br>
<input type="text" name="music.name" placeholder="音乐名"><br>
<input type="text" name="music.author" placeholder="音乐作者"><br>
<input type="submit" value="提交">
</form>
2、@InitBinder处理参数
@InitBinder
里的值,就是处理Controller层,方法参数里对应注解@ModelAttribute
里的参数的。
@ControllerAdvice
public class GlobalConfig {
@InitBinder("book")
public void initBook(WebDataBinder binder){
// 设置字段的前缀
binder.setFieldDefaultPrefix("book.");
}
@InitBinder("music")
public void initMusic(WebDataBinder binder){
binder.setFieldDefaultPrefix("music.");
}
3、Controller层处理
@RestController
public class StudentController {
@GetMapping("/bookAndMusic")
public String bookAndMusic(@ModelAttribute("book")Book book, @ModelAttribute("music")Music music){
return book.toString() + "----------" + music.toString();
}
4、测试结果