SpringMVC之参数校验注解@Valid
程序员文章站
2022-07-12 19:41:18
...
注解介绍
以上基本是所有注解了。
注解使用
- 实体类中添加注解
@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说明没有错误(相当于没有注解)。
这样一个注解就定义好了,使用方式和上面一开始一模一样。