顾名思义,@ControllerAdvice就是@Controller 的增强版。@ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用。
全局异常处理
@ControllerAdvice最常见的使用场景就是全局异常处理。比如文件上传大小限制的配置,如果用户上传的文件超过了限制大小,就会抛出异常,此时可以通过@ControllerAdvice结合@ExceptionHandler定义全局异常捕获机制,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
   | @ControllerAdvice public class CustomExceptionHandler {     @ExceptionHandler(MaxUploadSizeExceededException.class)     public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException {         resp.setContentType("text/html;charset=utf-8");         System.out.println(1111);         PrintWriter out = resp.getWriter();         out.write("上传文件大小超出限制!");         out.flush();         out.close();     } }
   | 
 
只需在系统中定义CustomExceptionHandler类,然后添加@ControllerAdvice注解即可。当系统启动时,该类就会被扫描到Spring容器中,然后定义uploadException方法,在该方法上添加了@ExceptionHandler注解,其中定义的MaxUploadSizeExceededException.class 表明该方法用来处理MaxUploadSizeExceededException类型的异常。如果想让该方法处理所有类型的异常,只需将MaxUploadSizeExceededException改为 Exception即可。方法的参数可以有异常实例、HttpServletResponse以及HttpServletRequest、Model 等,返回值可以是一段JSON、一个ModelAndView、一个逻辑视图名等。
添加全局数据
@ControllerAdvice是一个全局数据处理组件,因此也可以在@ControllerAdvice中配置全局数据,使用@ModelAttribute注解进行配置,代码如下:
1 2 3 4 5 6 7 8 9 10
   | @ControllerAdvice public class GlobalConfig {     @ModelAttribute(value = "info")     public Map<String, String> userInfo() {         HashMap<String, String> map = new HashMap<>();         map.put("username", "罗贯中");         map.put("gender", "男");         return map;     } }
   | 
 
在全局配置中添加userInfo方法,返回一个map。该方法有一个注解@ModelAttribute,其中的value属性表示这条返回数据的key,而方法的返回值是返回数据的value。
        此时在任意请求的Controller 中,通过方法参数中的Model都可以获取info 的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | public class MyController {     @GetMapping("/hello")     @ResponseBody     public void hello(Model model) {         Map<String, Object> map = model.asMap();         Set<String> keySet = map.keySet();         Iterator<String> iterator = keySet.iterator();         while (iterator.hasNext()) {             String key = iterator.next();             Object value = map.get(key);             System.out.println(key + ">>>>>" + value);         }     } }
  | 
 
请求参数预处理
@ControllerAdvice结合@InitBinder还能实现请求参数预处理,即将表单中的数据绑定到实体类上时进行一些额外处理。
例如有两个实体类 Book和 Author,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | @Data @AllArgsConstructor @NoArgsConstructor @Component @ToString public class Book {     private String name;     private String author;     @JsonIgnore     private Float price;     @JsonFormat(pattern = "yyyy-MM-dd")     private Date publicationDate; } @Data @AllArgsConstructor @NoArgsConstructor @ToString public class Author {     private String name;     private int age; }
   | 
 
在 Controller 上需要接收两个实体类的数据,Controller 中的方法定义如下:
1 2 3 4 5 6 7 8 9 10 11 12
   | @ControllerAdvice public class GlobalConfig1 {     @InitBinder("b")     public void init(WebDataBinder binder) {         binder.setFieldDefaultPrefix("b.");     }
      @InitBinder("a")     public void init2(WebDataBinder binder) {         binder.setFieldDefaultPrefix("a.");     } }
   | 
 
代码解释:
在 GlobalConfig类中创建两个方法,第一个@InitBinder(“b”)表示该方法是处理@ModelAttribute(“b”)对应的参数的,第二个@InitBinder(“a”)表示该方法是处理@ModelAttribute(“a”)对应的参数的。
        在每个方法中给相应的 Field设置一个前缀,然后在浏览器中请求http:/ocalhost:8080/book?b.name=三国演义&b.author=罗贯中&a.name=曹雪芹&a.age=48,即可成功地区分出name属性。
        在WebDataBinder对象中,还可以设置允许的字段、禁止的字段、必填字段以及验证器等。
==参考==
原文链接:https://blog.csdn.net/qq_43581790/article/details/123871439
    
    
     
评论区
欢迎你留下宝贵的意见,昵称输入QQ号会显示QQ头像哦~