IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> JSR303自定义注解校验 -> 正文阅读

[开发测试]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) {}  ```

 




  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-13 17:47:30  更:2021-07-13 17:49:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 1:46:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码