spring validation,自定义校验时间注解

news/2024/11/29 22:44:25/

广告:

话费充值优惠公众号: 惠享乐生活服务

前言:

前端传入的时间需要小于当前时间,因此想到了通过自定义注解实现,就无需在代码中写校验逻辑了。

1. 创建LocalDateTimeRange注解

package com.luck.living.validation;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;/*** @author xhga*/
@Target(value = {ElementType.METHOD,ElementType.FIELD,ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,ElementType.PARAMETER,ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = LocalDateTimeRangeValidator.class
)
public @interface LocalDateTimeRange {String message() default "时间范围不正确";String pattern() default "yyyy-MM-dd HH:mm:ss";// 最小值String min() default "";// 最大值String max() default "";// 最小值取当前时间,即:参数需大于当前时间boolean minUseCurrentDate() default false;// 最大值取当前时间,即:参数需小于当前时间boolean maxUseCurrentDate() default false;Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};}

2. 创建校验类

package com.luck.living.validation;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;/*** @author xhga*/
public class LocalDateTimeRangeValidator implements ConstraintValidator<LocalDateTimeRange, LocalDateTime> {private LocalDateTime minDate;private LocalDateTime maxDate;boolean minUseCurrentDate = false;boolean maxUseCurrentDate = false;private boolean parseFail = false;@Overridepublic void initialize(LocalDateTimeRange constraintAnnotation) {minUseCurrentDate = constraintAnnotation.minUseCurrentDate();maxUseCurrentDate = constraintAnnotation.maxUseCurrentDate();try {if (!constraintAnnotation.min().isEmpty()) {minDate = LocalDateTime.parse(constraintAnnotation.min(), DateTimeFormatter.ofPattern(constraintAnnotation.pattern()));}if (!constraintAnnotation.max().isEmpty()) {maxDate = LocalDateTime.parse(constraintAnnotation.max(), DateTimeFormatter.ofPattern(constraintAnnotation.pattern()));}} catch (Exception e) {parseFail = true;}}@Overridepublic boolean isValid(LocalDateTime value, ConstraintValidatorContext context) {if (minUseCurrentDate) {minDate = LocalDateTime.now();}if (maxUseCurrentDate) {maxDate = LocalDateTime.now();}if (parseFail) {return false;}// 如果value为null,返回true,因为这里只校验日期是否在范围内,不校验是否为nullif (value == null) {return true;}// 如果minDate和maxDate都为null,不进行校验,返回trueif (minDate == null && maxDate == null) {return true;}// 如果minDate不为null,且value小于minDate,返回falseif (minDate != null && value.isBefore(minDate)) {return false;}// 如果maxDate不为null,且value大于maxDate,返回falsereturn maxDate == null || !value.isAfter(maxDate);}
}

3. 使用LocalDateTimeRange注解

// createTimeEnd需小于当前时间
@LocalDateTimeRange(maxUseCurrentDate = true)
private LocalDateTime createTimeEnd;

与其他注解一样@LocalDateTimeRange与@Valid 搭配使用

注意:

遇到一个坑,我之前把当前时间的赋值写在了initialize方法,由于initialize只会在初始化时执行,导致比较当前时间时,只有第一次校验是取得当前时间,后续都是取得第一次的时间。

因此需要将获取当前时间的逻辑放在isValid方法。

// 错误代码    
@Overridepublic void initialize(LocalDateTimeRange constraintAnnotation) {try {if (constraintAnnotation.minUseCurrentDate()) {minDate = LocalDateTime.now();} else if (!constraintAnnotation.min().isEmpty()) {minDate = LocalDateTime.parse(constraintAnnotation.min(), DateTimeFormatter.ofPattern(constraintAnnotation.pattern()));}if (constraintAnnotation.maxUseCurrentDate()) {maxDate = LocalDateTime.now();} else if (!constraintAnnotation.max().isEmpty()) {maxDate = LocalDateTime.parse(constraintAnnotation.max(), DateTimeFormatter.ofPattern(constraintAnnotation.pattern()));}} catch (Exception e) {parseFail = true;}}


http://www.ppmy.cn/news/1212368.html

相关文章

基于STM32单片机抢答器设计

**单片机设计介绍&#xff0c; 基于STM32单片机抢答器设计-Proteus仿真 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于STM32单片机的抢答器设计可以用于教育和培训场景中的抢答游戏或考试环节。以下是一个基本的介绍设计步骤…

Linux 设置静态IP(Ubuntu 20.04/18.04)

以Ubuntu20.04示例 第一步&#xff1a;查看当前网络信息 ifconfig 本机网卡名为&#xff1a;ens32&#xff0c;IP地址为&#xff1a;192.168.15.133&#xff0c;子网掩码为&#xff1a;255.255.255.0 第二步&#xff1a;查看当前网关信息 route -n 网关地址为&#xff1a;1…

Linux学习教程(第二章 Linux系统安装)3

第二章 Linux系统安装 十一、Linux远程管理协议&#xff08;RFB、RDP、Telnet和SSH&#xff09; 提到远程管理&#xff0c;通常指的是远程管理服务器&#xff0c;而非个人计算机。个人计算机可以随时拿来用&#xff0c;服务器通常放置在机房中&#xff0c;用户无法直接接触到…

Spring Bean循环依赖问题及解决

什么是循环依赖 类与类之间的依赖关系形成了闭环&#xff0c;就会导致循环依赖问题的产生。举例来说&#xff0c;假设存在两个服务类A和服务类B&#xff0c;如果A通过依赖注入的方式引用了B&#xff0c;且B通过依赖注入的方式引用了A&#xff0c;那么A和B之间就存在循环依赖。…

postgreSQL中的TOAST技术

摘要&#xff1a;介绍postgreSQL中的TOAST技术 ​ TOAST&#xff08;The Oversize-Attribute Storage Technique&#xff09;技术是PG提供的一种存储大数据的机制。 ​ 要理解TOAST&#xff0c;我们要先理解页&#xff08;BLOCK&#xff09;的概念。在PG中&#xff0c;页是数据…

【数据结构初阶】顺序表SeqList

描述 顺序表我们可以把它想象成在一个表格里面填数据&#xff0c;并对数据做调整&#xff1b; 那我们的第一个问题是&#xff1a;怎么样在创建出足够的空间呢&#xff1f; 我们可以去堆上申请&#xff0c;用一个指针指向一块空间&#xff0c;如果申请的空间不够&#xff0c;我…

制作麒麟V10-server-sp2镜像

1.挂载iso 文件到目录 mount -o loop /xxx.iso /mnt 这样mnt 目录下会有iso 解压相关的文件 2.修改源文件内容 vim /etc/yum.repos.d/ kylin_x86_64.repo 将里面的所有的源enabled 都改成 0 并添加一个新的源 [ks10-local] name Kylin Linux Advanced Server 10 - Local base…

Python与ArcGIS系列(四)在地图文档中加入图层

目录 0 简述1 将图层添加到地图文档中2 将图层插入到地图文档0 简述 本篇介绍如何利用arcpy实现将图层添加到地图文档中,以及将图层插入到地图文档指定的位置。 1 将图层添加到地图文档中 arcpy的mapping模块提供的AddLayer()函数可以实现将图层添加到地图文档中。功能本质上…