欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringMVC之参数校验注解@Valid

程序员文章站 2022-07-12 19:41:18
...

注解介绍

SpringMVC之参数校验注解@Valid
SpringMVC之参数校验注解@Valid

以上基本是所有注解了。


注解使用

  • 实体类中添加注解
@Data
public class User {
    @Range(min = 0,max = 100,message = "年龄必须在0~100之间")
    private Integer age;

    private String name;

    @Length(min = 8,message = "密码不能少于八位")
    private String password;
}
  • controller接收
    @PostMapping("/user")
    public int addUser(@Valid @RequestBody User user, BindingResult errors) {
        if (errors.hasErrors()){ //是否有错误
            errors.getAllErrors().stream().forEach(error -> {
                FieldError fieldError = (FieldError) error;
                String err = fieldError.getField() + " : " + fieldError.getDefaultMessage();
                System.err.println(err);
            });
            return 0;
        }
        int result = userService.insertUser(user);
        return result;
    }

必须配合@Valid才有效,BindingResult是捕获注解的异常。

  • 单元测试
@Test
    public void whenPostInfoSuccess() throws Exception {
        String content = "{\"age\":110,\"name\":\"张三\",\"password\":\"123456\"}";
        String result = mockMvc.perform(MockMvcRequestBuilders.post("/user")
                //数据格式json
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(content))
                //返回状态是否200
                .andExpect(status().isOk())
                .andReturn().getResponse().getContentAsString();
        System.out.println("============" + result);
    }

我们参数age大于100,密码个数小于8位,这时执行单元测试,打印出:

age : 年龄必须在0~100之间
password : 密码不能少于八位

注解扩展

虽然上面提供很多校验的注解,但有时还是难以满足我们的需求,这时我们就需要自定义校验注解,再配合@Valid使用。

  • 自定义一个注解
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
//指定校验逻辑在哪个类中
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyUnique {
    String message() default "{参数错误}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

注意:@Constraint(validatedBy = MyConstraintValidator.class)是指该注解具体校验逻辑在哪个类中实现。
注解里面的三个属性是必须的(暂时没理解),当然也可以添加属性。

  • MyConstraintValidator类实现ConstraintValidator接口
/**
 * 该类可直接使用@Autowired注入bean
 * MyUnique :定义的注解
 * Object:需验证字段的类型
 */
public class MyConstraintValidator implements ConstraintValidator<MyUnique, Object> {
    @Autowired
    private UserService userService;

    public Logger logger = Logger.getLogger(MyConstraintValidator.class);

    /**
     * 初始化方法
     *
     * @param myUnique 定义的注解
     */
    @Override
    public void initialize(MyUnique myUnique) {

    }

    /**
     *
     * @param o
     * @param constraintValidatorContext
     * @return {@code false} if {@code value} does not pass the constraint
     */
    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        logger.info("====属性值=======" + o);
        int result = userService.getCountName(o);
        return result <= 0;
    }

isValid方法是具体的实现逻辑,返回false说明有错误,返回ture说明没有错误(相当于没有注解)。

这样一个注解就定义好了,使用方式和上面一开始一模一样。

相关标签: responsebody