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

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 的实现。

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

相关文章:

  • nid修改orac库和实例名为jyc
  • 无人机之模拟图传篇
  • Ubuntu 20.04安装pycharm2022及配置快捷方式
  • uni-app - - - - - 实现锚点定位和滚动监听功能(滚动监听功能暂未添加,待后续更新)
  • wordpress迁移到别的服务器
  • cefsharp新版本OnBeforeResourceLoad 禁止http自动跳转https显示404错误解决办法 含代码
  • RK 方案如何做到上电关机
  • 基于量子通讯进行安全认证
  • C语言贪吃蛇小游戏演示和说明
  • C++三大特性——继承性(超万字详解)
  • electron使用npm install出现下载失败的问题
  • HT513 2.8W I2S 输入单声道D类音频功率放大器
  • [PICO VR]Unity如何往PICO VR眼镜里写持久化数据txt/json文本
  • zico2打靶记录
  • pick你的第一个人形机器人——青龙强化学习环境测试
  • 了解主机及进程资源占用情况、性能情况、性能瓶颈,TOP命令输出解释
  • 计算机网络-小型综合网络的搭建涉及到无线路由交换安全
  • CleanClip For Mac 強大的剪貼簿助手Paste替代工具 v2.2.1
  • python全栈学习记录(十八)re、os和sys、subprocess
  • GO Fsnotify学习与使用
  • 除了递归算法,要如何优化实现文件搜索功能
  • 【AI算法岗面试八股面经【超全整理】——NLP】
  • Unity 设计模式 之 创建型模式 -【单例模式】【原型模式】 【建造者模式】
  • CSS中的字体样式、文本样式、列表样式以及背景和渐变
  • 教你如何在Java中操作Redis
  • nsight-system教程
  • 进程的那些事--进程控制
  • FortiOS SSL VPN 用户访问权限配置
  • C++_vector类
  • Spring Boot入门到精通:网上购物商城系统