JSR303自定义注解校验

JSR303自定义注解校验

1.常见校验注解
@Null
	带注解的元素必须为null,接受任何类型
    
@NotNull
	带注解的元素必须为null,接受任何类型
  
@NotEmpty
	带注解的元素不得为null或为空。
	支持的类型有:
	CharSequence (评估字符序列的长度)
	Collection (评估集合大小)
	Map (评估地图大小)
	数组(计算数组长度)

@NotBlank
  带注解的元素不能为null并且必须至少包含一个非空白字符。 接受CharSequence
      
@Min
  带注解的元素必须是一个数字,其值必须大于或等于指定的最小值。
	支持的类型有:
		BigDecimal
		BigInteger
		byteshortintlong和它们各自的包装器
	请注意,由于舍入错误,不支持doublefloat (某些提供程序可能会提供一些近似支持)
	null元素被认为是有效的。
  
@Max
	带注解的元素必须是一个数字,其值必须小于或等于指定的最大值。
	支持的类型有:
		BigDecimal
		BigInteger
		byteshortintlong和它们各自的包装器
	请注意,由于舍入错误,不支持doublefloat (某些提供程序可能会提供一些近似支持)
	null元素被认为是有效的

@DecimalMin(value=, inclusive=) // inclusive为true,则大于且等于,反之大于
	带注释的元素必须是一个数字,其值必须大于或等于指定的最小值。
	支持的类型有:
		BigDecimal
		BigInteger
		CharSequence
		byteshortintlong和它们各自的包装器
	请注意,由于舍入错误,不支持doublefloat (某些提供程序可能会提供一些近似支持)
	null元素被认为是有效的
    
@DecimalMax(value=, inclusive=) // inclusive为true,则小于且等于,反之小于
	带注释的元素必须是一个数字,其值必须小于或等于指定的最大值。
	支持的类型有:
		BigDecimal
		BigInteger
		CharSequence
		byteshortintlong和它们各自的包装器
	请注意,由于舍入错误,不支持doublefloat (某些提供程序可能会提供一些近似支持)
	null元素被认为是有效的
    
@Size(min=, max=)
	带注解的元素大小必须在指定的边界(包括)之间。
	支持的类型有:
	CharSequence (评估字符序列的长度)
	Collection (评估集合大小)
	Map (评估地图大小)
	数组(计算数组长度)
	null元素被认为是有效的
    
@Length(min=, max=)
  验证字符串是否介于包含的最小值和最大值之间
    
@Range(min=, max=)  // hibernae-validator
	带注解的元素必须在适当的范围内。 应用于数值或数值的字符串表示形式。

@Email(regexp=, flags=)	// 该字符串必须是格式正确的电子邮件地址    
@Pattern     // 带注解的元素必须匹配给定的正则
@AssertTrue  // 带注解的元素必须为true
@AssertFalse // 带注解的元素必须为false
@Digits      // 带注解的元素必须在指定的范围之内
@Future
	带注解元素必须是未来的某个时刻、日期或时间。
	现在由附加到ValidatorValidatorFactoryClockProvider定义。 默认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.初始化
<!-- 
	初始化一个Springboot工程,引入注解校验依赖
	springboot-starter-web中依赖了 spring-boot-starter-validation 无需额外引入
-->
<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.定义对象
/**
 * 定义一个java bean对象
 * 给Student对象添加一些校验注解
 */
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());
        /**
         * 输出结果如下:
         * 1
         * 最小不能小于18
         */
    }
}
2.4.接口调用测试
// 控制层定义如下接口。利用@Valid注解开启校验功能,利用BindingResult获取验证的结果
@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();
            // TODO: handle error msg, and return error response
        });
     } else {
         // go on...
    }
    return "成功";
}

通过postman接口调用传入json参数

{
  "name": "zhuyz",
  "age": 10
}
// 和单元测试一致,提示:最小不能小于18
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;

/**
 * message属性:这个属性被用来定义默认得消息模版, 当这个注解校验失败的时候,通过此属性来输出错误信息
 *      可以使用指定的错误描述文件中的信息来提示
 *
 * groups 属性:用于指定注解属于哪(些)个校验组, 这个的默认值必须是Class<?>类型到空到数组
 *
 * payload 属性:Bean Validation API 的使用者可以通过此属性来给约束条件指定严重级别. 这个属性并不被API自身所使用
 *
 * @Constraint(validatedBy = {ListValueConstraintValidator.class}) 关联自定义校验器
 * @Target:指定该注解可以被用在哪些位置(方法、字段、注解、构造器、方法参数等等)
 * @Retention(RUNTIME):运行时通过反射被读取
 *
 */
@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;

/**
 * 自定义注解校验器
 * 需要指定泛型:ConstraintValidator<A extends Annotation, T> A:校验注解,T代表被校验元素的类型
 */
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);
        }
    }

  	// 校验逻辑,true:校验成功,反之失败
    @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.接口测试
  • 定义对象
/**
* 定义一个java bean对象
* 给Student对象添加一些校验注解
*/
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;

}
  • 创建接口
// 控制层定义如下接口。利用@Valid注解开启校验功能,利用BindingResult获取验证的结果
@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();
           // TODO: handle error msg, and return error response
       });
    } else {
        // go on...
   }
   return "成功";
}
  • 通过postman传参调用接口
 {  "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})
// 如果Validated中填写的分组在属性的groups范围之内,则代表校验该属性,如果不在,则不进行校验
@PostMapping("/test/valid")
public String testBeanValid(@Validated({AddGroup.class}) @RequestBody Student student, BindingResult result) {}  ```

 




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Spring Boot使用JSR 303(Bean Validation)规范来实现数据校验。下面是Spring Boot中JSR 303的实现原理: 1. 配置依赖:在Spring Boot项目的pom.xml文件中,添加依赖项,通常是`spring-boot-starter-validation`。这将导入Hibernate Validator作为默认的JSR 303实现。 2. 引入注解:在需要校验数据的类的字段上使用JSR 303相关的注解,例如`@NotNull`、`@Size`、`@Min`、`@Max`等。 3. 校验过程:当Spring Boot接收到请求并绑定请求参数到相应的对象时,会自动触发数据校验校验过程由Spring MVC框架负责,它会根据注解的配置信息对字段进行校验。 4. 错误处理:如果校验失败,Spring Boot会将错误信息封装到`BindingResult`对象中,并将其添加到方法参数中。开发者可以根据需要处理错误信息,例如返回自定义的错误响应。 5. 配置全局校验器:可以通过配置类或属性文件来自定义全局的校验器设置,例如指定校验消息的国际化资源文件、设置校验器模式等。 6. 自定义校验注解:除了使用JSR 303提供的注解外,开发者还可以自定义校验注解。需要创建一个自定义注解,并编写对应的校验器类来实现具体的校验逻辑。 总的来说,Spring Boot通过使用JSR 303规范和Hibernate Validator来实现数据校验功能。开发者只需要添加相关的注解和依赖,就能轻松地实现数据校验,并在校验失败时进行相应的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值