JSR303自定义注解校验
1.常见校验注解
@Null
带注解的元素必须为null,接受任何类型
@NotNull
带注解的元素必须为null,接受任何类型
@NotEmpty
带注解的元素不得为null或为空。
支持的类型有:
CharSequence (评估字符序列的长度)
Collection (评估集合大小)
Map (评估地图大小)
数组(计算数组长度)
@NotBlank
带注解的元素不能为null并且必须至少包含一个非空白字符。 接受CharSequence
@Min
带注解的元素必须是一个数字,其值必须大于或等于指定的最小值。
支持的类型有:
BigDecimal
BigInteger
byte 、 short 、 int 、 long和它们各自的包装器
请注意,由于舍入错误,不支持double和float (某些提供程序可能会提供一些近似支持)
null元素被认为是有效的。
@Max
带注解的元素必须是一个数字,其值必须小于或等于指定的最大值。
支持的类型有:
BigDecimal
BigInteger
byte 、 short 、 int 、 long和它们各自的包装器
请注意,由于舍入错误,不支持double和float (某些提供程序可能会提供一些近似支持)
null元素被认为是有效的
@DecimalMin(value=, inclusive=)
带注释的元素必须是一个数字,其值必须大于或等于指定的最小值。
支持的类型有:
BigDecimal
BigInteger
CharSequence
byte 、 short 、 int 、 long和它们各自的包装器
请注意,由于舍入错误,不支持double和float (某些提供程序可能会提供一些近似支持)
null元素被认为是有效的
@DecimalMax(value=, inclusive=)
带注释的元素必须是一个数字,其值必须小于或等于指定的最大值。
支持的类型有:
BigDecimal
BigInteger
CharSequence
byte 、 short 、 int 、 long和它们各自的包装器
请注意,由于舍入错误,不支持double和float (某些提供程序可能会提供一些近似支持)
null元素被认为是有效的
@Size(min=, max=)
带注解的元素大小必须在指定的边界(包括)之间。
支持的类型有:
CharSequence (评估字符序列的长度)
Collection (评估集合大小)
Map (评估地图大小)
数组(计算数组长度)
null元素被认为是有效的
@Length(min=, max=)
验证字符串是否介于包含的最小值和最大值之间
@Range(min=, max=)
带注解的元素必须在适当的范围内。 应用于数值或数值的字符串表示形式。
@Email(regexp=, flags=)
@Pattern
@AssertTrue
@AssertFalse
@Digits
@Future
带注解元素必须是未来的某个时刻、日期或时间。
现在由附加到Validator或ValidatorFactory的ClockProvider定义。 默认clockProvider根据虚拟机定义当前时间,如果需要应用当前默认时区。
支持的类型有:
java.util.Date
java.util.Calendar
java.time.Instant
java.time.LocalDate
java.time.LocalDateTime
java.time.LocalTime
java.time.MonthDay
java.time.OffsetDateTime
java.time.OffsetTime
java.time.Year
java.time.YearMonth
java.time.ZonedDateTime
java.time.chrono.HijrahDate
java.time.chrono.JapaneseDate
java.time.chrono.MinguoDate
java.time.chrono.ThaiBuddhistDate
null元素被认为是有效的
@Past
2.整合java代码简单使用示例
2.1.初始化
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
2.2.定义对象
public class Student {
@NotNull
private String name;
@Min(18)
@Max(40)
private Integer age;
private String address;
private String url;
private String phone;
private Integer sex;
private Integer salary;
private String email;
}
2.3.单元测试
@ExtendWith(MockitoExtension.class)
@DisplayName("JSR303注解校验类")
public class JSR303Valid {
private static Validator validator;
@BeforeEach
void setUp() {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
validator = validatorFactory.getValidator();
}
@Test
@DisplayName("test @NotEmpty")
void testValid() {
Student student = new Student();
student.setName("zhuyz").setAge(10);
Set<ConstraintViolation<Student>> validate = validator.validate(student);
System.out.println(validate.size());
System.out.println(validate.iterator().next().getMessage());
}
}
2.4.接口调用测试
@PostMapping("/test/valid")
public String testBeanValid(@Valid @RequestBody Student student, BindingResult result) {
if (result.hasErrors()) {
result.getFieldErrors().stream().forEach(item -> {
String message = item.getDefaultMessage();
String field = item.getField();
});
} else {
}
return "成功";
}
通过postman接口调用传入json参数
{
"name": "zhuyz",
"age": 10
}
3.自定义注解校验
3.1.创建自定义校验注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Documented
@Constraint(validatedBy = {ListValueConstraintValidator.class})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.zhuyz.common.valid.ListValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] vals() default {};
}
3.2.创建自定义校验器与自定义校验注解关联
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
3.3.定义默认的验证错误信息
在resource路径下定义一个错误信息描述文件:ValidationMessages.properties
com.zhuyz.common.valid.ListValue.message=必须提交指定的值
3.4.接口测试
public class Student {
private String name;
private Integer age;
private String address;
private String url;
private String phone;
@ListValue(vals={0, 1})
private Integer sex;
private Integer salary;
private String email;
}
@PostMapping("/test/valid")
public String testBeanValid(@Valid @RequestBody Student student, BindingResult result) {
if (result.hasErrors()) {
result.getFieldErrors().stream().forEach(item -> {
String message = item.getDefaultMessage();
String field = item.getField();
});
} else {
}
return "成功";
}
{ "name": "zhuyz", "age": 10, "sex": 3}
4.分组校验
public interface ValidGroups { interface AddGroup { } interface UpdateGroup { }}
@NotBlank(message="name必须提交", groups={AddGroup.class, UpdateGroup.class})private String name;
- 在需要校验的位置添加@Validated({AddGroup.class})
@PostMapping("/test/valid")
public String testBeanValid(@Validated({AddGroup.class}) @RequestBody Student student, BindingResult result) {} ```
|