当前位置: 首页 > news >正文

SpringBoot利用ConstraintValidator实现自定义注解校验

一、前言

        ConstraintValidator是Java Bean Validation(JSR-303)规范中的一个接口,用于实现自定义校验注解的校验逻辑。ConstraintValidator定义了两个泛型参数,分别是注解类型和被校验的值类型。在实现ConstraintValidator接口时,需要重写initialize、isValid等方法,并实现具体的校验逻辑。

二、自定义注解校验参数是否为Null

        比如校验参数name不能为null或者空字符串,先编写@interface类ValidNull:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {NullValidator.class})
public @interface ValidNull {// 默认错误消息String message() default "name不能为空";// 分组Class<?>[] groups() default {};// 负载Class<? extends Payload>[] payload() default {};
}

        再编写校验类 NullValidator:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class NullValidator implements ConstraintValidator<ValidNull, String> {@Overridepublic void initialize(ValidNull constraintAnnotation) {ConstraintValidator.super.initialize(constraintAnnotation);}@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if (null == value || "".equals(value)){return false;}return true;}
}

        编写实体类NullTest,并在此加上注解:

import lombok.Data;@Data
public class NullTest {@ValidNullprivate String name;
}

         最后在controller层进行调用校验,注意需要在实体类前面加上@Validated 注解,否则校验是不生效的:

    @PostMapping(value = "/test")public RetResult test(@RequestBody @Validated NullTest nullTest) {System.err.println(nullTest.getName());return RetResult.success();}

        测试结果:

        当name有值时,正常通过:

         当name为null时,提示校验错误信息:

        当name为空字符串时, 提示校验错误信息:

 

三、自定义注解校验参数值大小

        比如一个参数是数字,需要校验其大小,方法如下:

        先编写@interface类:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {NumValidator.class})
public @interface ValidNum {int value();// 默认错误消息String message() default "num不能大于20";// 分组Class<?>[] groups() default {};// 负载Class<? extends Payload>[] payload() default {};
}

        这里有添加value,这个可以在使用该注解时,传参数,下面的默认错误信息,也可以在使用注解时一起使用,只是在没有传参数时默认使用而已。

        编写NumValidator校验类:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class NumValidator implements ConstraintValidator<ValidNum,Integer> {private Integer value;@Overridepublic void initialize(ValidNum constraintAnnotation) {this.value = constraintAnnotation.value();}@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {if(value > this.value){return false;}return true;}
}

        可以看到这里也定义了value,在initialize里面初始化,也就是获取使用该注解的地方传入的值。

        编写实体类NullTest:

import lombok.Data;@Data
public class NumTest {@ValidNum(value = 30, message = "数值不能大于30")private Integer num;
}

        在controller层测试:

    @PostMapping(value = "/test")public RetResult test(@RequestBody @Validated NumTest numTest) {System.err.println(numTest.getNum());return RetResult.success();}

        测试结果:

        当传入参数小于30时:

        当传入参数大于30时:

 

http://www.lryc.cn/news/137999.html

相关文章:

  • 十、pikachu之php反序列化
  • PHP“牵手”拼多多商品详情数据获取方法,拼多多API接口批量获取拼多多商品详情数据说明
  • 前端面试:【Redux】状态管理的精髓
  • element-ui中的el-table的summary-method(合计)的使用
  • “深入探索JVM:解析Java虚拟机的工作原理与性能优化“
  • 【后端】Core框架版本和发布时间以及.net 6.0启动文件的结构
  • Linux 定时任务 crontab 用法学习整理
  • 看板之道:如何利用Kanban优化您的项目流程
  • Docker的基础操作
  • 14、缓存预热+缓存雪崩+缓存击穿+缓存穿透
  • 【PostGreSQL】PostGreSQL到Oracle的数据迁移
  • jupyter notebook出现ERR_SSL_VERSION_OR_CIPHER_MISMATCH解决方案
  • 前端进阶Html+css10----定位的参照对象(高频面试题)
  • 总结记录Keras开发构建神经网络模型的三种主流方式:序列模型、函数模型、子类模型
  • python环境建设
  • Python学习笔记第五十九天(Matplotlib 安装)
  • (6)(6.3) 自动任务中的相机控制
  • 什么是cssreset ?为什么要用到cssreset?
  • SpringCloud学习笔记(四)_ZooKeeper注册中心
  • 【算法专题突破】双指针 - 移动零(1)
  • Nginx高可用集群
  • Rust 基础入门 ——所有权 引言 :垃圾自动回收机制的缺陷。
  • Ubuntu20.04安装软件报错:The following packages have unmet dependencies
  • Java 与设计模式(12):享元模式
  • React配置代理(proxy)
  • 队列(Queue):先进先出的数据结构队列
  • CentOS ens160 显示disconnected
  • 使用 ChatGPT 创建 PowerPoint 演示文稿
  • matlab将数组值划分为两类
  • 【点击新增一个下拉框 与前一个内容一样 但不能选同一个值】