Javax Validation 自定义注解校验(身份证号校验)
一、场景分析
我们使用 SpringMVC 在 Controller 层,对身份证号进行数据校验的话,经常采用以下方式:
@RestController
@RequiredArgsConstructor
@RequestMapping("member")
public class MemberController {// 身份证号码正则表达式String regex = "^(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}[0-9Xx]$)$";@PostMapping("/register")public R<Void> register(@RequestBody @Valid Member member) {Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(member.getIdNo());if (!matcher.matches()) {return R.fail("不是有效的身份证号");}System.out.println(member);return R.success();}
}
我们当然可以采用上面的方式进行数据校验,但这种方式不是很优雅:
如果项目中还有别的对象需要进行身份证号校验,那么同样的代码就会在项目里散落一地。
Javax Validation 提供给我们另一种优雅的方式,进行逻辑重复的数据校验。
二、代码实现
1、创建自定义校验注解
首先创建一个自定义的校验注解,用于校验字符串是否为有效的身份证号格式
package com.study.annotations;import com.study.config.IdCheckValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {IdCheckValidator.class}
)
public @interface IdCheck {String message() default "不是有效的身份证号";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
2、创建校验器实现类
创建一个实现 ConstraintValidator 接口的类来实现自定义校验逻辑
package com.study.config;import com.study.annotations.IdCheck;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class IdCheckValidator implements ConstraintValidator<IdCheck, String> {// 身份证号码正则表达式String regex = "^(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}[0-9Xx]$)$";@Overridepublic void initialize(IdCheck constraintAnnotation) {ConstraintValidator.super.initialize(constraintAnnotation);}@Overridepublic boolean isValid(String idNo, ConstraintValidatorContext constraintValidatorContext) {Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(idNo);return matcher.matches();}
}
3、在实体类中使用自定义注解
package com.study.member.entity;import com.study.annotations.IdCheck;
import lombok.Data;@Data
public class Member {// 自定义注解@IdCheckprivate String idNo;
}
4、在控制器中进行数据绑定和校验
package com.study.member.controller;import com.study.memberentity.Member;
import com.study.common.base.R;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;@RestController
@RequiredArgsConstructor
@RequestMapping("member")
public class MemberController {@PostMapping("/register")public R<Void> register(@RequestBody @Valid Member member) {System.out.println(member);return R.success();}
}
5、测试
输入一个格式错误的身份证号:
###
POST http://localhost:8080/member/register
Content-Type: application/json
{"idNo": "811111111111111111"}
输出:
{"code": -1,"msg": "不是有效的身份证号"
}
输入一个格式正确的身份证号(该身份证号是我随机生成的):
###
POST http://localhost:8080/member/register
Content-Type: application/json
{"idNo": "12010319881011691X"}
输出:
{"code": 0,"msg": "success"
}
三、总结
ConstraintValidator 是 javax validation 规范提供给我们的一个实现数据校验的接口。
像 hibernate.validator 就有很多这个接口的实现,像我们常见的
- NotNullValidator
- MaxValidatorForMonetaryAmount
- MinValidatorForMonetaryAmount
等都是它的实现。以上代码,参考 NotNullValidator 的实现。
相关文章:

Javax Validation 自定义注解校验(身份证号校验)
一、场景分析 我们使用 SpringMVC 在 Controller 层,对身份证号进行数据校验的话,经常采用以下方式: RestController RequiredArgsConstructor RequestMapping("member") public class MemberController {// 身份证号码正则表达式…...

nid修改orac库和实例名为jyc
由于库太大,并且要求修改源库的实例名,所以考虑采用nid方式重建控制文件,实现名称和路径的完美替换。 oracleJYCDB:/home/oracle/scripts> oracleJYCDB:/home/oracle/scripts>echo $ORACLE_SID orac oracleJYCDB:/home/oracle/scripts…...

无人机之模拟图传篇
无人机的模拟图传技术是一种通过模拟信号传输图像数据的方式,它通常使用无线电模块或专用通信协议进行数据传输。 一、基本原理 模拟图传技术的工作原理是将摄像头或相机设备采集到的图像数据,通过模拟信号的形式进行传输。这些模拟信号在传输过程中可能…...

Ubuntu 20.04安装pycharm2022及配置快捷方式
一、下载与安装 1. 下载 在 官网 下载所需版本,如:下载 2022.3.3 - Linux (tar.gz) 2. 安装 设置自定义安装路径(推荐在 /opt/ 路径下)并安装 mkdir -p ~/Documents/software/pycharm/ cd ~/Documents/software/pycharm/ mv ~/Downloads/pycharm-c…...

uni-app - - - - - 实现锚点定位和滚动监听功能(滚动监听功能暂未添加,待后续更新)
实现锚点定位和滚动监听功能 1. 思路解析2. 代码示例 效果截图示例: 点击左侧menu,右侧列表数据实现锚点定位 1. 思路解析 点击左侧按钮,更新右侧scroll-view对应的scroll-into-view的值,即可实现右侧锚点定位滚动右侧区域&am…...

wordpress迁移到别的服务器
wordpress论坛网站搭建 于2023/11/16写的该文章 一-配置环境 配置LNMP(linuxnginxmysqlphpphpmyadmin)环境或者LAMP(apache) 可以选择集成了这些软件的套件 下载链接:https://www.xp.cn/download.html 手动下载这…...

cefsharp新版本OnBeforeResourceLoad 禁止http自动跳转https显示404错误解决办法 含代码
一、问题 因项目需要,域名没有ssl证书,结果http访问时被强制定向到https前缀,结果会显示404 测试版本cefsharp126.x (x64) 框架 CefSharp.WinForms.NETCore 二、代码(核心代码) 如果请求url是http,且目标是https时,则阻止请求 //判断请求变化 if (url.StartsWith(<…...

RK 方案如何做到上电关机
针对RK方案,公版都是上电开机的,有时候有要求需要上电关机,按键开机,需要把PMU的VDC脚的相关电路去掉即可,只保留一个对地电容。这时候就是上电关机了。RP43/RP47/RP64 电阻都去掉。 沟通交流群QQ:71228861…...

基于量子通讯进行安全认证
8月16日,中国银行的一项发明专利“安全认证方法、装置、电子设备及计算机存储介质”授权公告。其申请于2022年6月29日,公布于2022年9月20日。据悉,该发明中应用了量子通讯/量子随机数相关技术。 事实上,近年来,有多家银行探索研究量子技术。在多家银行的2024半年报中,就…...

C语言贪吃蛇小游戏演示和说明
C语言贪吃蛇小游戏演示和说明 设计贪吃蛇游戏的主要目的是让大家夯实C语言基础,训练编程思维,培养解决问题的思路,领略多姿多彩的C语言。 游戏开始后,会在中间位置出现一条只有三个节点的贪吃蛇,并随机出现一个食物&am…...

C++三大特性——继承性(超万字详解)
目录 前言 一、封装 1. 封装(Encapsulation) 二、继承 1. 构造函数的调用顺序 原理: 2. 析构函数的调用顺序 原理: 3、派生类的隐藏 1. 成员函数隐藏 2. 成员变量隐藏 3. 基类函数的重载隐藏 三、多重继承问题 1. 构…...

electron使用npm install出现下载失败的问题
我在使用electron进行下载时,经常出现一个错误。 HTTPError: Response code 404 (Not Found) for https://registry.npmmirror.com/v21.4.4/electron-v21.4.4-win32-x64.zip 这个时候需要修改一些npm的配置。使用命令npm config list -ls 滑到下面,找到一…...

HT513 2.8W I2S 输入单声道D类音频功率放大器
1 特性 ● 电源供电 PVDD 2.5-6.5V; DVDD/AVDD 3.3V ● 灵活的音频输入: I2S,LJ, RJ TDM 输入 8,16,32,44.1,48,88.2,96,192kHz 采样频率输出功率: 1.40W(PVDD3.6V,RL4Ω,THDN10%) 2.80W(PVDD5.0V,RL4Ω,THDN10%) 4.70W(PVDD6.5V,RL4Ω,THDN10%) ● THDN0.08%(Po1W, …...

[PICO VR]Unity如何往PICO VR眼镜里写持久化数据txt/json文本
前言 最近在用PICO VR做用户实验,需要将用户实验的数据记录到PICO头盔的存储空间里,记录一下整个过程 流程 1.开启写入权限 首先开启写入权限:Unity->Edit->Player->安卓小机器人->Other Settings->Configuration->Wri…...

zico2打靶记录
一、环境搭建 下载地址:https://download.vulnhub.com/zico/zico2.ova 直接双击下载的.ova文件即可在VMware中打开 设置好保存路径后在虚拟机的设置中删除仅主机这个网卡 然后启动靶机 二、信息收集 扫描靶机ip arp-scan -l 扫描一下开放的端口 nmap -p- -sV…...

pick你的第一个人形机器人——青龙强化学习环境测试
文章目录 一、环境配置二、开始训练三、训练成果 最近感受到的大趋势是具身智能,强化学习,模仿学习做人形机器人,这个赛道很火,颇有前些年全力投入做自动驾驶的架势,正好最近用强化学习解决POMDP问题接触到了强化学习&…...

了解主机及进程资源占用情况、性能情况、性能瓶颈,TOP命令输出解释
列表前的字段解释 字段通俗解释top - 03:08:50 up 19:36当前时间是 03:08:50,系统已经运行了 19 小时 36 分钟1 user当前有 1 个用户登录使用系统load average: 0.00, 0.02, 0.00系统在过去 1 分钟、5 分钟和 15 分钟内平均的工作繁忙程度,数值越大表示越忙 对于一个 x个核的…...

计算机网络-小型综合网络的搭建涉及到无线路由交换安全
目录 1 拓扑架构 2 做项目的思路 3 做配置 3.1先做核心交换 3.2 防火墙的配置 4 ac 和ap 的配置 4.1 ac上配置安全的东西 5.1 测试编辑 1 拓扑架构 要求看上面的图 2 做项目的思路 这张网很明显是一个小综合,设计到我们的无线交换,路由…...

CleanClip For Mac 強大的剪貼簿助手Paste替代工具 v2.2.1
软件介绍: CleanClip是一款专为Mac设计的强大剪贴板管理工具,旨在提升用户的工作效率和生产力。这款应用完全采用原生Swift编写,为Mac用户提供了流畅、快速且直观的使用体验。CleanClip不仅支持文本内容的管理,还能处理图片、文件…...

python全栈学习记录(十八)re、os和sys、subprocess
re、os和sys、subprocess 文章目录 re、os和sys、subprocess一、re1.正则字符2.正则表达式的使用3.group的使用4.贪婪匹配与惰性匹配5.其他注意事项 二、os和sys1.os2.sys 三、subprocess四、打印进度条 一、re python中的re模块用来使用正则表达式,正则就是用一系…...

GO Fsnotify学习与使用
文章目录 说明demo 说明 fsnotify 是 Go 的一个文件系统通知库,可以监视文件或目录的变化。基本用法如下: 安装库: go get github.com/fsnotify/fsnotify创建 watcher: watcher, err : fsnotify.NewWatcher() if err ! nil {log.…...

除了递归算法,要如何优化实现文件搜索功能
大家好,我是 V 哥,今天的文章来聊一聊 Java实现文件搜索功能,并且比较递归算法、迭代方式和Memoization技术的优缺点。 以下是一个使用 Java 实现的文件搜索功能,它会在指定目录及其子目录中搜索包含特定关键字的文件。此实现使用…...

【AI算法岗面试八股面经【超全整理】——NLP】
AI算法岗面试八股面经【超全整理】 概率论【AI算法岗面试八股面经【超全整理】——概率论】信息论【AI算法岗面试八股面经【超全整理】——信息论】机器学习【AI算法岗面试八股面经【超全整理】——机器学习】深度学习【AI算法岗面试八股面经【超全整理】——深度学习】NLP【A…...

Unity 设计模式 之 创建型模式 -【单例模式】【原型模式】 【建造者模式】
Unity 设计模式 之 创建型模式 -【单例模式】【原型模式】 【建造者模式】 目录 Unity 设计模式 之 创建型模式 -【单例模式】【原型模式】 【建造者模式】 一、简单介绍 二、单例模式 (Singleton Pattern) 1、什么时候使用单例模式 2、单例模式的好处 3、使用单例模式的…...

CSS中的字体样式、文本样式、列表样式以及背景和渐变
一、字体样式和文本样式 1.span标签 span标签的作用:能让某几个文字或者是词语凸显出来 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-…...

教你如何在Java中操作Redis
Redis的Java客户端 Redis 的 Java 客户端很多,常用的几种: Jedis:基于 Java 的 Redis 客户端,提供了 Redis 命令的全面支持。Lettuce:高性能的 Java 客户端库,用于与 Redis 数据库进行交互。它支持同步、…...

nsight-system教程
一 安装 参考 nsight-compute使用教程-CSDN博客https://blog.csdn.net/youzjuer/article/details/142549332 二 使用 nsys profile -t cuda,nvtx --force-overwrite true -o xxxx python xxx.py xxxx表示生成文档的名字 如果是cuda c 则 python xxx.py替换为./xxx即可 这…...

进程的那些事--进程控制
目录 前言 一、创建进程 二、退出进程 void exit (int retval) 三、进程等待 四、进程替换 前言 提示:这里可以添加本文要记录的大概内容: 前面我们认识了进程,现在让我们认识几个进程的接口 提示:以下是本篇文章正文内容…...

FortiOS SSL VPN 用户访问权限配置
简介 使用不同用户组或用户登录 SSL VPN 隧道模式后,可配置不同的访问权限。 本文介绍为不同用户组分配不同访问权限的配置方法。 相关组件 FortiGate:FortiOS v6.4.14 build2093 (GA) 客户端:Windows11,安装 FortiClient VPN 7.…...

C++_vector类
欢迎来到本期节目- - - vector类 本期直接先上代码,然后以代码为例介绍需要注意的问题. 模拟实现: #pragma once #include<iostream> #include<assert.h> using namespace std;namespace my_room {template<class T>class vector{p…...