Introduction to @ControllerAdvice

Introduction to @ControllerAdvice

1. What is @ControllerAdvice

First of all, @ControllerAdvice is essentially a @Component, so it will also be scanned as a component. ​ The classes added with @ControllerAdvice are specialized
insert image description here
for classes that declare @ExceptionHandleror annotate modified methods for sharing by multiple Controller classes. To put it bluntly, it is an implementation of the aop idea. You tell me that you need interception rules, and I will help you to block them. Specifically, if you want to do more detailed interception screening and processing after interception, you can pass or these three annotations yourself . And the method annotated by it to customize.@InitBinder@ModelAttribute@Component@ExceptionHandler@InitBinder @ModelAttribute

  • @ExceptionHandler annotation annotation method: used to capture different types of exceptions thrown in the Controller, so as to achieve the purpose of global exception processing.
  • @InitBinder annotation annotation method: used to register custom parameter parsing in the request, so as to achieve the purpose of customizing the request parameter format.
  • @ModelAttribute annotation method: indicates that this method will be executed before executing the target Controller method.

2. How to use

ControllerAdvice provides a variety of ways to specify Advice rules. By default, nothing is written, and it is all Advice Controllers. Of course, you can also specify rules in the following ways:

1. Designated package

//匹配com.xzh.cn包及其子包下的所有Controller
@ControllerAdvice(basePackages="com.xzh.cn")
//数组形式指定
@ControllerAdvice(basePackages={
    
    "com.xzh.cn", "com.xzh.cn.controller"}),

2. Specify annotations

//匹配所有被这个注解修饰的 Controller,也可以匹配自定义的注解
@ControllerAdvice(annotations={
    
    RestController.class})

3. @ModelAttribute(default global data)

Use @ModelAttribute to store data before controller request

// 1.无返回值方法,放入Model,自定义 key ,value
@ModelAttribute()
public void presetParam(Model model) {
    
    
    model.addAttribute("globalAttr", "我是全局参数");
}
// 2.不有指定name,返回值方法,返回值是map,int等,key就是map,int等,,value是返回值
@ModelAttribute()
public Map<String, String> presetParam2() {
    
    
    Map<String, String> map1 = new HashMap<String, String>();
    map1.put("key1", "value1");
    return map1;
}
// 3.指定name,返回值方法,key就是name,value是返回值
@ModelAttribute(name = "map2")
public Map<String, String> presetParam3() {
    
    
    Map<String, String> map = new HashMap<String, String>();
    map.put("key2", "value2");
    return map;
}
// 4.可以接受请求参数
@ModelAttribute()
public void presetParam4(@RequestParam("name") String name,Model model) {
    
    
    model.addAttribute("name", name);
}

Take out the data:

 //1.使用Model取出
@GetMapping("model")
public String methodOne(Model model) {
    
    
    Map<String, Object> modelMap = model.asMap();
    System.out.println(modelMap.get("name").toString()); // 传入name的值    
    return modelMap.get("globalAttr").toString();
}
//2.使用ModelMap取出
@GetMapping("modelMap")
public String methodThree(ModelMap modelMap) {
    
    
    return modelMap.get("map").toString();
}
//3.@ModelAttribute()指定key,直接取出
@GetMapping("modelAttribute")
public String methodTwo(@ModelAttribute("map2") Map map2) {
    
    
    return map2.toString();
}

4. @ExceptionHandler(Handling global exceptions)

//处理BindException异常信息
@ExceptionHandler(BindException.class)
@ResponseBody
public Result exceptionHandler(BindException e, BindingResult result) {
    
    
   //逻辑处理
   return new Result();
}

//通用异常处理器,所有Exception异常都由这里处理
@ExceptionHandler(Exception.class)
@ResponseBody
public Result exceptionHandler(Exception e) {
    
    
    return new Result();
}

5. @InitBinder(Request parameter preprocessing)

Use the default property editor:

@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    
    
    /*
     * 创建一个字符串微调编辑器
     * 参数{boolean emptyAsNull}: 是否把空字符串("")视为 null
     */
    StringTrimmerEditor trimmerEditor = new StringTrimmerEditor(true);
    /*
     * 注册自定义编辑器
     * 接受两个参数{Class<?> requiredType, PropertyEditor propertyEditor}
     * requiredType:所需处理的类型
     * propertyEditor:属性编辑器,StringTrimmerEditor就是 propertyEditor的一个子类
     */
    dataBinder.registerCustomEditor(String.class, trimmerEditor);
    //日期格式的字符串转换成Date对象
    dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), false));
    dataBinder.addValidators(paramVOValidator);
}

Custom property editor:

/**
 * @description:  防止xss注入
 * @params:  String类型转换,将所有传递进来的String进行HTML编码,防止XSS攻击
 */
//@InitBinder
protected void initBinder2(WebDataBinder binder) {
    
    
    //自定义属性编辑器 PropertyEditorSupport
    binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
    
    
        @Override
        public void setAsText(String text) {
    
    
            setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
        }
        @Override
        public String getAsText() {
    
    
            Object value = getValue();
            return value != null ? value.toString() : "";
        }
    });
}

Custom parameter validation @Validated:

@Data
public class User implements Serializable {
    
    

    @ApiModelProperty("age")
    private Integer age;
    
    @ApiModelProperty("name")
    private String name;
}

@Component
public class UserValidator implements Validator {
    
    

	/**
	* @description:  满足条件才往下走
	* @params:
	* @return:
	*/
    @Override
    public boolean supports(Class<?> clazz) {
    
    
        // 只支持ParamVO类型对象的校验
        return User.class.equals(clazz);
    }

    /**
    * @description:  自定义校验规则
    * @params:
    * @return:
    */
    @Override
    public void validate(Object target, Errors errors) {
    
    
        User user = (User) target;
        String userName = user.getName();
        if (StringUtils.isEmpty(userName) || userName.length() < 8) {
    
    
            errors.rejectValue("name", "valid.userNameLen", new Object[]{
    
    "minLength", 8}, "用户名不能少于8位");
        }
    }
}

@Autowired
private UserValidator userValidator;
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    
    
    dataBinder.addValidators(userValidator);
}

Guess you like

Origin blog.csdn.net/weixin_48453772/article/details/131128711