@ControllerAdvice三种使用场景

Posted 半瓶牛奶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@ControllerAdvice三种使用场景相关的知识,希望对你有一定的参考价值。

主要来源于:https://www.cnblogs.com/lenve/p/10748453.html
Spring中的注解

@ControllerAdvice作用:

  • 处理全局异常
  • 预设全局数据
  • 请求参数预处理

处理全局异常

@ControllerAdvice结合 @ExceptionHandler使用,处理全局异常。

使用@ControllerAdvice可以将所有的@ExceptionHandler方法都集中在一个类中,统一处理

  • @ControllerAdvice默认拦截所有控制器
  • @ControllerAdvice(annotaions={UserController.class})配置指定需要拦截的控制器
  • ControllerAdvice(basePackages = "com.demo") 配置需要拦截的指定路径下的控制器

使用@ContollerAdvice可以实现全局异常处理(SpringBoot有专门的处理异常机制,可见``),实现方式如下:

@ControllerAdvice
public class GlobalExceptoonHandler(){
	@ExceptionHandler(Exception.class)
    //指定要处理的异常类型,可以返回页面模板,也可以返回json数据
	public ModelAndView customeException(Exception e){
		ModelAndView mv = new ModelAndView();
		mv.addObject("message",e);
		mv.setViewName("my error view");
		return mv;
	}
}

@ExcwptionHandler标识的方法返回值和@RequestMapping的规则统一。

  • ModelAndView对象
  • String,这里指的是ModelAndView的路径
  • 进一步使用了@ResponseBody注解,这时返回的String,是字符串了

全局数据绑定

@ControllerAdvice结合 @ModelAttribute使用,全局数据绑定。

有一些初始数据的操作,我们可以将一些公共的数据定义在添加了@ControllerAdvice类中,这样所有的Controller接口, 都能访问到这些数据,如下:

  1. 定义全局数据
@ControllerAdvice
public class MyGlobalExceptionHandler {
    //标记该方法的返回数据是一个全局数据,默认key是返回的变量名(下面方法即为 map),value是方法返回值
    //可以通过 @ModelAttribute 注解的 name 属性去重新指定 key(下面方法即为 md)。
     @ModelAttribute(name = "md")
    public Map<String,Object> mydata() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("age", 99);
        map.put("gender", "男");
        return map;
    }
}
  1. 在controller使用全局变量

    @RestController
    public class HelloController {
        @GetMapping("/hello")
        public String hello(Model model) {
            // 获取数据
            Map<String, Object> map = model.asMap();
            System.out.println(map);
            return "hello controller advice";
        }
    }
    
    // {md={age=99, gender=男}}
    

// TODO @ModelAttribute 详解

全局数据预处理

接口同时接收两个类,两个类中参数名相同时,从前端传递时无法区分,通过 @ControllerAdvice结合@ModelAttribute 的全局数据预处理可以解决这个问题,如下:

  1. 给接口中的变量取别名
@PostMapping("/book")
public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) {
    System.out.println(book);
    System.out.println(author);
}

2.进行请求数据预处理
在 @ControllerAdvice 标记的类中添加如下代码:

//注解表示该方法用来处理和Book和相关的参数,在方法中,给参数添加一个 b 前缀,即请求参数要有b前缀.
@InitBinder("b")
public void b(WebDataBinder binder) {
    binder.setFieldDefaultPrefix("b.");
}
@InitBinder("a")
public void a(WebDataBinder binder) {
    binder.setFieldDefaultPrefix("a.");
}

image-20210516204413833

以上是关于@ControllerAdvice三种使用场景的主要内容,如果未能解决你的问题,请参考以下文章

Bean初始化操作-SpringMVC中@ControllerAdvice注解的三种使用场景

Bean初始化操作-SpringMVC中@ControllerAdvice注解的三种使用场景

SpringMVC 中 @ControllerAdvice 注解的三种使用场景!

一网打尽 @ExceptionHandlerHandlerExceptionResolver@controlleradvice 三兄弟!

springboot 使用@ControllerAdvice注解全局处理系统异常

SpringBoot学习13:springboot异常处理方式3(使用@ControllerAdvice+@ExceptionHandle注解)