Spring Boot之@ControllerAdvice

  • @ControllerAdvice就是@Controller增强版
  • @ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler@ModelAttribute@InitBinder使用

全局异常处理

方法的参数可以有异常实例,HttpServletRequestHttpServletResponseModel

方法的返回值可以是一段JSON,一个ModelAndView,一个逻辑视图名等

  1. 直接处理
@ControllerAdvice
public class CustomExceptionHandler {

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.write("上传文件大小超出限制!");
        out.flush();
        out.close();
    }
}
  1. 返回ModelAndView
// 1.设置全局异常处理
@ControllerAdvice
public class CustomExceptionHandler2 {

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ModelAndView uploadException(MaxUploadSizeExceededException e) throws IOException {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", "上传文件大小超出限制...");
        modelAndView.setViewName("error");
        return modelAndView;
    }
}
<!-- 2.导入thymeleaf依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 3.resource目录下的templates目录下添加error.html -->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div th:text="${msg}"></div>
</body>
</html>

添加全局数据

  1. 添加全局数据
@ControllerAdvice
public class GlobalConfig {

    @ModelAttribute(value = "info")
    public Map<String,String> userInfo() {
        HashMap<String, String> map = new HashMap<>();
        map.put("author", "罗贯中");
        map.put("gender", "男");
        return map;
    }
}
  1. 取出全局数据
@GetMapping("/hello")
public void hello(Model model) {
    Iterator<Map.Entry<String, Object>> iterator = model.asMap().entrySet().iterator();
    while (iterator.hasNext()){
        Map.Entry<String, Object> map = iterator.next();
        String key = map.getKey();
        Object value = map.getValue();
        System.out.println(key + ": " + value);
        //info: {gender=男, author=罗贯中}
    }
}

请求参数预处理

@ControllerAdvice结合@InitBinder还能实现请求参数预处理,即将表单中的数据绑定到实体类上进行一些额外处理。

  1. 参数传递时,两个实体类的name属性混淆
public class Author {
    private String name;
    private int age;
    //setter getter...
}

public class Book {
    private String name;
    private String author;
    //setter getter...
}

@GetMapping("/book")
@ResponseBody
public String book(Book book, Author author) {
    return book.toString() + ">>>" + author.toString();
}

//请求:http://localhost:8080/book?name=张三&age=18&name=三国演义&author=罗贯中
//返回数据:Book{name='张三,三国演义', author='罗贯中'}>>>Author{name='张三,三国演义', age=18}
  1. 参数预处理,解决两个Bean同名属性混淆
// 1.将Controller方法参数通过@ModelAttribute("a")绑定属性a和b
@GetMapping("/book")
@ResponseBody
public String book(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author){
    return book.toString() + ">>>" + author.toString();
}

// 2.1在ControllerAdvice中用@InitBinder("a")来表示处理@ModelAttribute("a")中的参数
// 2.2通过WebDateBinder来设置字段前缀
@ControllerAdvice
public class GlobalConfig2 {

    @InitBinder("b")
    public void init(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("b.");
    }

    @InitBinder("a")
    public void init2(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("a.");
    }
}

//请求:http://localhost:8080/book?a.name=张三&a.age=18&b.name=三国演义&b.author=罗贯中
//返回数据:Book{name='三国演义', author='罗贯中'}>>>Author{name='张三', age=18}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/04/01/controlleradvice-of-spring-boot/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Spring Boot之@ControllerAdvice
@ControllerAdvice就是@Controller增强版 @ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute、@InitBinder使用 全局异常……
<<上一篇
下一篇>>
文章目录
关闭
目 录