validation参数检验 - 注解介绍

2023-05-16

文章目录

  • Maven 依赖
  • 注解介绍
    • javax.validation 中的注解(22个)
      • Null、NotNull
      • NotBlank
      • NotEmpty
      • Size
      • AssertFalse、AssertTrue
      • DecimalMax、DecimalMin、Max、Min
      • Digits
      • Positive、PositiveOrZero、Negative、NegativeOrZero
      • Future、FutureOrPresent、Past、PastOrPresent
      • Email、Pattern
    • hibernate.validator 中的注解
      • DurationMax、DurationMax
      • Length
      • Range
      • UniqueElements
  • 使用技巧
    • 自定义 message、读取配置文件
  • 问题
    • 为什么同是基本类型,boolean、int 对 null 的处理不同?

Maven 依赖

项目为 springboot 项目,主要依赖有以下三个,其中spring-boot-starter-validation包含了 jakarta.validation-api(包含了 javax.validation)、hibernate-validator

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-validation</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>

	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
	</dependency>

注解介绍

javax.validation 中的注解(22个)

javax.validation 中的注解

注解验证的数据类型说明
Null所有类型验证元素值必须为 null
NotNull所有类型验证元素值必须不为 null
NotBlankCharSequence验证元素值不能为 null,并且至少包含一个非空白字符。
NotEmptyCharSequence、Collection、Map、Array验证元素值不能为 null,且不能为空
Size(min = min, max = max)同 NotEmpty验证元素的 size 必须在 min 和 max 之间(包含边界),认为 null 是有效的
AssertFalseboolean、Boolean验证元素值必须为 false,认为 null 是有效的
AssertTrue同 AssertFalse验证元素值必须为 true,认为 null 是有效的
DecimalMax(value=, inclusive=)BigDecimal、BigInteger、CharSequence,byte、 short、int、long 及其包装类型,由于舍入错误,不支持double和float验证元素值必须小于等于指定的 value 值,认为 null 是有效的
DecimalMin同 DecimalMax验证元素值必须大于等于指定的 value 值,认为 null 是有效的
Max同 DecimalMax,不支持CharSequence验证元素值必须小于等于指定的 value 值,认为 null 是有效的
Min同 DecimalMax,不支持CharSequence验证元素值必须大于等于指定的 value 值,认为 null 是有效的
Digits(integer =, fraction =)同 DecimalMax验证元素整数位数的上限 integer 与小数位数的上限 fraction,认为 null 是有效的
PositiveBigDecimal、BigInteger,byte、short、int、long、float、double 及其包装类型验证元素必须为正数,认为 null 是有效的
PositiveOrZero同Positive验证元素必须为正数或 0,认为 null 是有效的
Negative同Positive验证元素必须为负数,认为 null 是有效的
NegativeOrZero同Positive验证元素必须为负数或 0,认为 null 是有效的
FutureDate、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate验证元素值必须是一个将来的时间,认为 null 是有效的
FutureOrPresent同 Future验证元素值必须是当前时间或一个将来的时间,认为 null 是有效的
Past同 Future验证元素值必须是一个过去的时间,认为 null 是有效的
PastOrPresent同 Future验证元素值必须是当前时间或一个过去的时间,认为 null 是有效的
Email(regexp = 正则表达式,flag = 标志的模式)CharSequence验证注解的元素值是Email,可以通过 regexp 和 flag 指定自定义的 email 格式,认为 null 是有效的
Pattern同 Email验证元素值符合正则表达式,认为 null 是有效的

Null、NotNull

验证元素值必须为 null (Null),必须不为 null(NotNull),支持所有类型。

    @GetMapping("null")
    public String isNull(@Null Integer b) {
        return "pass: " + b;
    }

    @GetMapping("notNull")
    public String notNull(@NotNull Integer b) {
        return "pass: " + b;
    }

Null_NotNull

NotBlank

验证元素值不能为null,并且至少包含一个非空白字符。支持的类型:CharSequence

    @GetMapping("notBlank")
    public String notBlank(@NotBlank String b) {
        return "pass: " + b;
    }

notBlank

NotEmpty

验证元素值不能为null,且不能为空。支持的类型:

  • CharSequence (length of character sequence is evaluated)
  • Collection (collection size is evaluated)
  • Map (map size is evaluated)
  • Array (array length is evaluated)
    @GetMapping("notEmpty")
    public String notEmpty(@NotEmpty @RequestParam(name = "list", required = false) ArrayList<String> list) {
        return "pass: " + list;
    }

notEmpty

Size

验证元素的size必须在 min 和 max 之间(包含边界),认为 null 是有效的。支持的类型:

  • CharSequence (length of character sequence is evaluated)
  • Collection (collection size is evaluated)
  • Map (map size is evaluated)
  • Array (array length is evaluated)

Size
min()
size 的最小值,默认为 0

max()
size 的最大值,默认为 Integer.MAX_VALUE

    @GetMapping("size")
    public String size(@Size(min = 2, max = 3) @RequestParam(name = "list", required = false) ArrayList<String> list ) {
        return "pass: " + list;
    }

size

AssertFalse、AssertTrue

验证元素值必须为false/true,认为 null 是有效的(见测试结果),支持booleanBoolean

    @GetMapping("wrapperAssertFalse")
    public String wrapperAssertFalse(@AssertFalse Boolean b) {
        return "pass: " + b;
    }

    @GetMapping("wrapperAssertTrue")
    public String wrapperAssertTrue(@AssertTrue Boolean b) {
        return "pass: " + b;
    }

    @GetMapping("primitiveAssertFalse")
    public String primitiveAssertFalse(@AssertFalse boolean b) {
        return "pass: " + b;
    }

    @GetMapping("primitiveAssertTrue")
    public String primitiveAssertTrue(@AssertTrue boolean b) {
        return "pass: " + b;
    }

测试结果

primitiveAssertTrue

wrapperAssertTrue

primitiveAssertFalse

wrapperAssertFalse

注解数据类型truefalsenull
@AssertTrue基本类型××
@AssertTrue包装类型×
@AssertFalse基本类型×
@AssertFalse包装类型×

关于 null 的特除处理
  在AssertTrueAssertFalse的 javadoc 中都有一句 null elements are considered valid,意思就是 null 被认为是有效的。那为什么 AssertTrue 对基本类型 boolean 会验证失败呢?我觉得是因为基本类型的默认值导致的,当前端传值为 null 时,Boolean会使用直接使用 null,但是基本类型不能为 null,所以boolean使用的是默认值 false,false != true,所以验证失败。

DecimalMax、DecimalMin、Max、Min

验证元素值必须小于等于 / 大于等于指定的 value 值,认为 null 是有效的。

  • BigDecimal
  • BigInteger
  • CharSequence,Max、Min 不支持
  • byte、short、int、long 及其包装类型
  • 由于舍入错误,不支持double和float

Max

DecimalMax
value() 方法
指定的最大、最小值

inclusive() 方法
验证时是否可以包含边界值(value()方法指定的值),默认为 true
Max、Min 不支持。

    @GetMapping("decimalMinInteger")
    public String decimalMinInteger(@DecimalMin(value = "10") Integer b) {
        return "pass: " + b;
    }

    @GetMapping("decimalMinInt")
    public String decimalMinInt(@DecimalMin(value = "10") int b) {
        return "pass: " + b;
    }
	
    @GetMapping("decimalMinIntegerExclusive")
    public String decimalMinIntegerExclusive(@DecimalMin(value = "10", inclusive = false) Integer b) {
        return "pass: " + b;
    }

decimalMinInteger
上图中使用的是包装类型 Integer, 有两个特殊情况:

  1. 当无法将字符串转换为对应数值类型时,会抛出异常,但此异常并不是验证失败,因为还没有走到验证那一步就报错了
  2. 当值为 null时,通过了验证

decimalMinInt
上图中使用的是基本类型 int,与图 decimalMinInteger 相比, 可以看出与 Integer 的区别,在于对 null 的处理,int 是直接抛出了异常,而 Integer 是通过了验证

decimalMinIntegerExclusive
上图中 inclusive = false,与图 decimalMinInteger 的第二个小图相比,图 decimalMinIntegerExclusive 没有通过验证。

Digits

验证元素整数位数的上限 integer 小数位数的上限 fraction,认为 null 是有效的。支持 BigDecimal、BigInteger、CharSequence,byte、 short、int、long 及其包装类型,由于舍入错误,不支持double和float

enter description here
integer()
整数位数的最大值

fraction()
小数位数的最大值

    @GetMapping("digits")
    public String digits(@Digits(integer = 2, fraction = 1) BigDecimal b) {
        return "pass: " + b;
    }

digits

Positive、PositiveOrZero、Negative、NegativeOrZero

验证元素必须为正数(Positive)、正数或 0 (PositiveOrZero)、负数(Negative)、负数或 0 (NegativeOrZero),认为 null 是有效的 ,支持的类型:

  • BigDecimal
  • BigInteger
  • byte、short、int、long、float、double 及其包装类型
    @GetMapping("positive")
    public String positive(@Positive Integer t) {
        return "pass: " + t;
    }

    @GetMapping("positiveOrZero")
    public String positiveOrZero(@PositiveOrZero Integer t) {
        return "pass: " + t;
    }

positive

positiveOrZero

Future、FutureOrPresent、Past、PastOrPresent

验证元素值必须是一个将来的时间(Future)、将来的时间或当前时间(FutureOrPresent)、过去的时间(Past)、过去的时间或当前时间(PastOrPresent),认为 null 是有效的 。此处 present 的概念是相对于使用约束的类型定义的。例如,如果约束条件是一年,那么当前时间就意味着整个当年。支持的类型:

  • 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
    @GetMapping("future")
   public String future(@Future LocalDate t) {
       return "pass: " + t;
   }

   @GetMapping("futureOrPresent")
   public String futureOrPresent(@FutureOrPresent LocalDate t) {
       return "pass: " + t;
   }

测试时间为 2020-04-30

future

futureOrPresent
测试时间为 2020-04-30,可以看到图 future、图 futureOrPresent 的第二张小图,一个验证失败,一个验证通过。

Email、Pattern

验证注解的元素值是Email(Email)、符合正则表达式(Pattern),可以通过 regexp 和 flag 指定自定义的 email、正则格式,认为 null 是有效的 ,支持的类型:CharSequence。

Email
regexp()
正则表达式,Email 默认为 .* 任意字符,Pattern无默认值。
flags()
指定正则的匹配模式,不会用(手动狗头)。

    @GetMapping("email")
    public String email(@Email(regexp = ".+@.+") String email) {
        return "pass: " + email;
    }

email

hibernate.validator 中的注解

hibernate.validator

注解数据类型说明
CreditCardNumber(ignoreNonDigitCharacters=)CharSequence检查字符序列是否通过Luhn校验和测试。请注意,此验证旨在检查用户错误,而不是信用卡有效性!ignoreNonDigitCharacters允许忽略非数字字符,默认值为false。
Currencyjavax.money.MonetaryAmount 子类型检查注解的货币单位 javax.money.MonetaryAmount 是否为指定货币单位的一部分
DurationMaxDuration注解的 Duration 必须小于等于 DurationMax 指定的值,默认包含边界
DurationMinDuration注解的 Duration 必须大于等于 DurationMax 指定的值,默认包含边界
EANCharSequence是否是有效的国际商品编号,null 是有效的
ISBNCharSequence是否是有效的国际标准书号,null 是有效的
LengthCharSequence长度必须在 min 和 max之间,包含边界
RangeBigDecimal、BigInteger、CharSequence,byte、 short、int、long 及其包装类型数字大小必须在 min 和 max 之间,包含边界
UniqueElementsCollection检测集合中的值都是唯一的(集合不能包含相同的元素,null 是有效的)
UrlCharSequence根据RFC2396检查字符序列是否为有效URL
LuhnCheckCharSequence检查字符序列中的数字是否通过Luhn校验和算法
Mod10CheckCharSequence检查字符序列中的数字是否通过通用mod 10校验和算法。
Mod11CheckCharSequence检查字符序列中的数字是否通过通用mod 11校验和算法。
ScriptAssert任意类型
CodePointLengthCharSequence
CNPJCharSequence验证巴西公司纳税人注册编号
CPFCharSequence验证巴西个人纳税人注册号
TituloEleitoralCharSequence验证巴西选民身份证号
NIPCharSequence验证波兰增值税标识号
PESELCharSequence验证波兰的国家标识号
REGONCharSequence验证波兰纳税人识别码

DurationMax、DurationMax

注解的 Duration 必须小于等于(DurationMax)、大于等于(DurationMin) 指定的值,默认包含边界。支持的类型 java.time.Duration

DurationMax

@RestController
public class HibernateController {

    private final HibernateService hibernateService;

    public HibernateController(HibernateService hibernateService) {
        this.hibernateService = hibernateService;
    }

    @GetMapping("durationMax")
    public String durationMax(long minutes) {
        Duration duration = Duration.ofMinutes(minutes);
        return "pass: " + hibernateService.durationMax(duration);
    }
}

@Validated
@Service
public class HibernateService {

    public long durationMax(@DurationMax(minutes = 2) Duration d) {
        return d.toMinutes();
    }
}

durationMax

Length

字符长度必须在 min 和 max之间,包含边界。支持的类型:CharSequence

Length

    @GetMapping("length")
    public String length(@Length(min = 2, max = 3) StringBuilder s) {
        return "pass: " + s.toString();
    }

length

Range

数字大小必须在 min 和 max 之间,包含边界。支持的类型:

  • BigDecimal
  • BigInteger
  • CharSequence
  • byte、 short、int、long 及其包装类型

Range

    @GetMapping("range")
    public String range(@Range(min = 3, max = 10) Integer s) {
        return "pass: " + s.toString();
    }

range

UniqueElements

检测集合中的值都是唯一的(集合不能包含相同的元素),null 是有效的。支持的类型:Collection

    @GetMapping("uniqueElements")
    public String uniqueElements(@UniqueElements @RequestParam("list") List<String> list) {
        return "pass: " + list;
    }

uniqueElements

使用技巧

自定义 message、读取配置文件

问题

为什么同是基本类型,boolean、int 对 null 的处理不同?

如下代码可以看出,在值为 null 时,spring 对 Boolean 进行的特殊处理,直接返回了 false,而对其他基本类型抛出了异常。

	// org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver
	
	@Nullable
	private Object handleNullValue(String name, @Nullable Object value, Class<?> paramType) {
		if (value == null) {
			if (Boolean.TYPE.equals(paramType)) {
				return Boolean.FALSE;
			}
			else if (paramType.isPrimitive()) {
				throw new IllegalStateException("Optional " + paramType.getSimpleName() + " parameter '" + name +
						"' is present but cannot be translated into a null value due to being declared as a " +
						"primitive type. Consider declaring it as object wrapper for the corresponding primitive type.");
			}
		}
		return value;
	}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

validation参数检验 - 注解介绍 的相关文章

  • 【RTD】AD7793两线式铂电阻PT100/PT1000应用

    文章目录 1 前言2 AD7793 两线式铂电阻测量2 1 阻值计算 3 小结 1 前言 上一篇文章描述的是RTD驱动芯片AD7793与四线式RTD连接使用方法 本文描述两线式RTD与AD7793的使用 相关文章 xff1a RTD 铂电阻
  • 【RTD】AD7793驱动程序

    文章目录 1 前言2 AD7793驱动程序2 1 spi访问接口2 2 寄存器和常用配置值2 3 初始化2 4 原始数据获取2 5 阻值换算 3 使用4 完整工程代码 1 前言 前面文章主要描述AD7793分别与两线 三线 四线RTD连接电
  • 【RTD】二分法查找和分段线性插值算法在RTD中应用

    文章目录 1 前言2 二分法查找2 1 复杂度2 2 实现 3 分段线性插值4 RTD实例 1 前言 处理器通过RTD采集电路 xff08 芯片 xff09 精确获得当前RTD电阻值后 xff0c 再结合RTD与温度线性关系表 xff0c
  • 24系列EEPROM/FRAM通用驱动库移植到RT-Thread

    文章目录 1 前言2 接口实现2 1 i2c收发函数实现2 2 页写延时函数2 3 写保护函数2 4 设备注册 3 对接RT Thread设备驱动3 1 标准设备驱动接口3 2 注册到RT Thread3 3 导出到msh3 4 测试 4
  • 【RT-Thread】TCA9534 8位I/O扩展器驱动软件包

    文章目录 1 简介1 1 目录结构1 2 许可证 2 芯片介绍3 支持情况4 使用说明4 1 依赖4 2 获取软件包4 3 初始化4 4 访问设备4 5 msh finsh测试查看设备注册执行sample 5 代码仓库 1 简介 tca95
  • 【代码质量】RAII在C++编程中的必要性

    文章目录 1 前言2 什么是RAII3 为什么用RAII4 RAII应用5 小结 1 前言 C C 43 43 相比其他高级编程语言 xff0c 具有指针的概念 xff0c 指针即是内存地址 C C 43 43 可以通过指针来直接访问内存空
  • C++ RAII典型应用之lock_guard和unique_lock模板

    文章目录 1 前言2 lock guard3 lock guard使用4 unique lock5 相关文章 1 前言 常用的线程间同步 通信 xff08 IPC xff09 方式有锁 xff08 互斥锁 读写锁 自旋锁 xff09 屏障
  • 基于STM32的实时操作系统FreeRTOS移植教程(手动移植)

    前言 xff1a 此文为笔者FreeRTOS专栏 下的第一篇基础性教学文章 xff0c 其主要目的为 xff1a 帮助读者朋友快速搭建出属于自己的公版FreeRTOS系统 xff0c 实现后续在实时操作系统FreeRTOS上的开发与运用 操
  • 通过sysinfo获取Linux系统状态信息

    系统运行状态信息是我们关注的重点 xff0c 通过当前系统的输出信息 xff0c 如内存大小 进程数量 运行时间等 xff0c 以便分析CPU负载 软硬件资源占用情况 xff0c 确保系统高效和稳定 Linux系统中 xff0c 提供sys
  • Keil AC5/Keil AC6/IAR指定数据绝对存储地址

    文章目录 1 前言2 实现方法3 例子 1 前言 编译过程中 xff0c 指定数据绝对存储地址在实际项目中会经常使用到或者必须用到 xff0c 这样使得项目实现某些功能可以非常灵活 xff0c 常用的场景有 xff1a IAP升级时候 xf
  • 嵌入式开发常用到的在线工具

    文章目录 IP地址计算常用加解密 xff0c AES DSE Base64 MD5异或 xff08 BCC xff09 校验CRC计算十六进制格式化字符串Json格式化HTML运行器常用在线编译器 xff08 C C 43 43 C JAV
  • STM32H7xx 串口DMA发送&接收(LL库)

    文章目录 1 前言2 STM32H7实现2 1 关键步骤2 2 注意事项 3 代码仓库 1 前言 关于串口DMA收发实现 xff0c 不同CPU其套路都是类似的 xff0c 不同之处在于寄存器配置 依赖BSP库等差异 串口DMA收发详细实现
  • 正交编码器溢出处理

    文章目录 1 正交编码器1 1 参数特性1 2 应用范围 2 正交编码器使用2 1 溢出问题2 2 中断模式2 3 循环模式延伸 1 正交编码器 正交编码器一般指的是增量式光栅 xff08 磁栅 xff09 编码器 xff0c 通常有三路输
  • PX4多旋翼期望姿态矩阵生成算法

    1 PX4多旋翼期望姿态生成算法 1 1 求期望体轴X轴向量1 2 求期望体轴Y轴向量1 3 求期望姿态矩阵1 4 求期望姿态角 1 PX4多旋翼期望姿态生成算法 PX4多旋翼期望姿态生成采用旋转矩阵方法 xff0c 基本思路为根据外环解算
  • git安装

    Git介绍 分布式 xff1a Git版本控制系统是一个分布式的系统 xff0c 是用来保存工程源代码历史状态的命令行工具 保存点 xff1a Git的保存点可以追踪源码中的文件 并能得到某一个时间点上的整个工程项目的状态 xff1b 可以
  • linux更改ssh连接方式将publickey改为用户名密码登录

    1 vim etc ssh sshd config 2 PermitRootLogin no 改为 PermitRootLogin yes 3 service restart sshd
  • dsp2812 pmsm foc之速度环电流环

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 速度环PI 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • leetcode(c++)

    放假没事刷几道leetcode xff0c 一些常见典型题的答案和解析 平时python用的比较多 xff0c 但分析复杂度的时候用python编程不方便 xff0c 所以刷题的时候用了c 43 43 C 43 43 基础 C 43 43
  • 基于STM32的超声波雷达项目【可拟合构建平面地图】(代码开源)

    前言 xff1a 本文为手把手教学基于STM32的超声波雷达 项目 HC SR04雷达 本次项目采用的是STM32作为MCU xff0c 搭配常用的HC SR04超声波模块与舵机SG90实现模拟雷达检测 的效果 模拟了雷达图UI 可以拟合构
  • android sdk manager不显示更新,只显示已安装,解决办法

    启动 Android SDK Manager xff0c 打开主界面 xff0c 依次选择 Tools Options xff0c 弹出 Android SDK Manager Settings 窗口 xff1b 在 Android SDK

随机推荐