Spring Boot 中 @ControllerAdvice 的几种简单使用 (@ExceptionHandler、@ModelAttribute、@InitBinder)

@ControllerAdvice 可以在 Spring Boot 中实现对一些功能的 AOP,通过 @ExceptionHandler、@ModelAttribute、@InitBinder 等注解来实现全局异常处理、全局数据管理以及参数预处理等功能。

全局异常处理

通过 @ControllerAdvice 与 @ExceptionHandler 就能够构建一个类似拦截器的功能,检测整个程式运行时候所发生的异常,并且根据不同的异常对他们进行相应的处理。比方说,在一个上传文件的功能中,我们设置了一个文件上传大小的限制。如果上传的文件超过了这个设定,就会报出 MaxUploadSizeExceededException 的异常。所以可以添加以下代码:

@ControllerAdvice
public class CustomExceptionHandler {

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public void maxUploadSizeExceededExceptionHandler(MaxUploadSizeExceededException e,
                                                      HttpServletResponse response) {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.write("文件上傳大小超過限制!");
            writer.flush();
        } catch (IOException exception) {
            exception.printStackTrace();
        } finally {
            writer.close();
        }
    }
}

出错时直接提示错误,当然这绝对不是真实开发中所用的方法,这里可以实现更多不同的解决方法来处理这个异常。

添加全局数据

@ControllerAdvice 注解搭配 @ModelAttribute 将可以添加全局数据,在前者标注的类中所建立的 Model Attribute 可以被所有 Controller 中的 model 读到。

GlobalConfig.java

@ControllerAdvice
public class GlobalConfig {

    @ModelAttribute("userInfo")
    public Map<String, String> userInfo() {
        Map<String, String> map = new HashMap<>();
        map.put("username", "andyching");
        map.put("gender", "Male");
        return map;
    }
}

UserController.java

@RestController
public class UserController {
    @GetMapping("/getUserInfo")
    public Object getUserInfo(Model model) {
        return model.getAttribute("userInfo");
    }
}

这样就能直接输出之前所保存的内容了。

请求参数预处理

@ControllerAdvice 还可以与 @InitBinder 一同使用,进行参数的预处理。以下有一个例子:

Author.java

public class Author {
    private String name;
    private String age;
  //... 省略 Getter、Setter 与 toString
}

Book.java

public class Book {
    private String name;
    private String author;
  //... 省略 Getter、Setter 与 toString
}

BookController.java

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

那么,在 url 请求的时候,比如 localhost:8080/book?author=Darvis&age=25 时,就会发现 name 属性将出现冲突,因此这时候就可以使用 @InitBinder 来解决这个冲突:

GlobalConfig.java

@ControllerAdvice
public class GlobalConfig {

    @InitBinder("book")
    public void initBook(WebDataBinder dataBinder) {
        dataBinder.setFieldDefaultPrefix("book.");
    }

    @InitBinder("author")
    public void initAuthor(WebDataBinder dataBinder) {
        dataBinder.setFieldDefaultPrefix("author.");
    }

}

这时候只要访问时标注它们的值就可以实现功能了:http://localhost:8080/book?book.name=萬有引力&author.name=達爾維斯&age=30&author=達爾維斯

另外,如果不想用同属性名的标记的话,可以做以下处理:

更改 BookController.java

@RestController
public class BookController {
    @GetMapping("/book")
    public String book(@ModelAttribute("b") Book book,
                       @ModelAttribute("a") Author author) {
        return book.toString() + ">>>" + author.toString();
    }
}

更改 GlobalConfig.java 为:

@ControllerAdvice
public class GlobalConfig {

    @InitBinder("b")
    public void initBook(WebDataBinder dataBinder) {
        dataBinder.setFieldDefaultPrefix("b.");
    }

    @InitBinder("a")
    public void initAuthor(WebDataBinder dataBinder) {
        dataBinder.setFieldDefaultPrefix("a.");
    }

}

然后实际的开发中一般不会用这种方式处理,这里就简单复习一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值