• @ControllerAdvice 与 @RestControllerAdvice


    1. @ControllerAdvice 与 @RestControllerAdvice的来源、关系、作用

    在Spring 3.2中,新增了@ControllerAdvice、@RestControllerAdvice 注解,都是对Controller进行增强,@RestControllerAdvice = @ControllerAdvice + @ResponseBody

    @ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用。

    @ControllerAdvice主要解决多Contrller中的共性问题,如公共的数据,全局异常处理,全局入参出参转换等。

    2. @ControllerAdvice + @ExceptionHandler

    平时的编码过程中,可以使用try-catch来捕获异常,通常添加try-catch是因为不添加,通过不了编译检查

    如果存在运行时异常,有没有加try-catch,就出现异常抛出至浏览器,如下图,体验非常不好

    并且,从错误信息可以分析出系统信息,非常的不安全,存在安全漏洞

    虽然可以通过加try-catch对异常进行捕捉,但无法保证所有的人,所有的方法,都正确的添加

    此时,可以使用 @ControllerAdvice结合@ExceptionHandler 用来实现全局异常处理(注意不能自己try和catch异常,否则就不会被全局异常处理捕获到)

    @ControllerAdvice:用来开启全局的异常捕获

    @ExceptionHandler:说明捕获哪些异常,对哪些异常进行处理。

    在该类中,可以在一个方法中处理所有的异常信息。

    1. @Slf4j
    2. @ControllerAdvice
    3. public class GlobalExceptionHandle {
    4. @ExceptionHandler
    5. public DataResp handlerException(Exception e){
    6. log.error("handlerException()-", e);
    7. DataResp resp = DataResp.fail(ErrorCodeEnum.E000009, "系统异常,请稍后重试");
    8. return resp;
    9. }
    10. }

    也可以定义多个方法,不同的方法处理不同的异常,返回不同的响应码与错误提示,例如专门处理空指针的方法、专门处理数组越界的方法...。

    相比与HandlerExceptionResolver接口而言,使用@ExceptionHandler更能灵活地对不同的异常进行分别的处理。并且,当抛出的异常是指定异常的子类,那么照样能够被捕获和处理。

    1. @ControllerAdvice
    2. public class ExceptionConfigController
    3. {
    4. // 专门用来捕获和处理Controller层的空指针异常
    5. @ExceptionHandler(NullPointerException.class)
    6. public ModelAndView nullPointerExceptionHandler(NullPointerException e){
    7. ModelAndView mv = new ModelAndView(new MappingJackson2JsonView());
    8. mv.addObject("success",false);
    9. mv.addObject("mesg","请求发生了空指针异常,请稍后再试");
    10. return mv;
    11. }
    12. // 专门用来捕获和处理Controller层的运行时异常
    13. @ExceptionHandler(RuntimeException.class)
    14. public ModelAndView runtimeExceptionHandler(RuntimeException e){
    15. ModelAndView mv = new ModelAndView(new MappingJackson2JsonView());
    16. mv.addObject("success",false);
    17. mv.addObject("mesg","请求发生了运行时异常,请稍后再试");
    18. return mv;
    19. }
    20. // 专门用来捕获和处理Controller层的异常
    21. @ExceptionHandler(Exception.class)
    22. public ModelAndView exceptionHandler(Exception e){
    23. ModelAndView mv = new ModelAndView(new MappingJackson2JsonView());
    24. mv.addObject("success",false);
    25. mv.addObject("mesg","请求发生了异常,请稍后再试");
    26. return mv;
    27. }
    28. }

    3. @ControllerAdvice + @ModelAttribute

    可以用来预设全局数据

    方式一:

    1. @ControllerAdvice
    2. public class MyGlobalHandler {
    3.     @ModelAttribute
    4.     public void presetParam(Model model){
    5.         model.addAttribute("globalAttr","this is a global attribute");
    6.     }
    7. }

    方式二:

    1. @ControllerAdvice
    2. public class MyGlobalHandler {
    3. @ModelAttribute()
    4. public Map presetParam(){
    5. Map map = new HashMap();
    6. map.put("key1", "value1");
    7. map.put("key2", "value2");
    8. map.put("key3", "value3");
    9. return map;
    10. }
    11. }

    当 @ModelAttribute() 不传任何参数的时候,默认会把返回值的字符串值作为key,如上例的 key 则是 ”map"(值得注意的是,不支持字符串的返回值作为key)。
    当 @ModelAttribute("myMap") 传参数的时候,则以参数值作为key,这里 key 则是 ”myMap“。

    取值:

    1. @RestController
    2. public class AdviceController {
    3. @GetMapping("methodOne")
    4. public String methodOne(Model model){
    5. Map modelMap = model.asMap();
    6. return (String)modelMap.get("globalAttr");
    7. }
    8. @GetMapping("methodTwo")
    9. public String methodTwo(@ModelAttribute("globalAttr") String globalAttr){
    10. return globalAttr;
    11. }
    12. @GetMapping("methodThree")
    13. public String methodThree(ModelMap modelMap) {
    14. return (String) modelMap.get("globalAttr");
    15. }
    16. }

    4. @ControllerAdvice + @InitBinder

    实现对请求参数的预处理

  • 相关阅读:
    销售团队可以借助CRM系统做什么?
    Linux4.4内核构建脚本分析(一)- vmlinux的构建
    tomcat+idea--如何在idea上发布项目
    ASA-HA-FO-A/S
    【模型推理加速系列】06: 基于resnet18加速方案评测
    使用Vsftpd服务传输文件
    Java中 Lambda表达式如何实现匿名函数
    十进制分钟转时间类型
    【LLM】主流大模型体验(文心一言 科大讯飞 字节豆包 百川 阿里通义千问 商汤商量)
    ROS create_wall_timer/create_timer函数区别
  • 原文地址:https://blog.csdn.net/hfaflanf/article/details/127117091