Javax Validation自定義注解進(jìn)行身份證號(hào)校驗(yàn)
一、場(chǎng)景分析
我們使用 SpringMVC 在 Controller 層,對(duì)身份證號(hào)進(jìn)行數(shù)據(jù)校驗(yàn)的話,經(jīng)常采用以下方式:
@RestController
@RequiredArgsConstructor
@RequestMapping("member")
public class MemberController {
// 身份證號(hào)碼正則表達(dá)式
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("不是有效的身份證號(hào)");
}
System.out.println(member);
return R.success();
}
}
我們當(dāng)然可以采用上面的方式進(jìn)行數(shù)據(jù)校驗(yàn),但這種方式不是很優(yōu)雅:
如果項(xiàng)目中還有別的對(duì)象需要進(jìn)行身份證號(hào)校驗(yàn),那么同樣的代碼就會(huì)在項(xiàng)目里散落一地。
Javax Validation 提供給我們另一種優(yōu)雅的方式,進(jìn)行邏輯重復(fù)的數(shù)據(jù)校驗(yàn)。
二、代碼實(shí)現(xiàn)
1、創(chuàng)建自定義校驗(yàn)注解
首先創(chuàng)建一個(gè)自定義的校驗(yàn)注解,用于校驗(yàn)字符串是否為有效的身份證號(hào)格式
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 "不是有效的身份證號(hào)";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2、創(chuàng)建校驗(yàn)器實(shí)現(xiàn)類
創(chuàng)建一個(gè)實(shí)現(xiàn) ConstraintValidator 接口的類來實(shí)現(xiàn)自定義校驗(yàn)邏輯
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> {
// 身份證號(hào)碼正則表達(dá)式
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]$)$";
private Pattern pattern;
@Override
public void initialize(IdCheck constraintAnnotation) {
// 初始化 pattern
this.pattern = Pattern.compile(regex);
}
@Override
public boolean isValid(String idNo, ConstraintValidatorContext constraintValidatorContext) {
Matcher matcher = pattern.matcher(idNo);
return matcher.matches();
}
}
3、在實(shí)體類中使用自定義注解
package com.study.member.entity;
import com.study.annotations.IdCheck;
import lombok.Data;
@Data
public class Member {
// 自定義注解
@IdCheck
private String idNo;
}
4、在控制器中進(jìn)行數(shù)據(jù)綁定和校驗(yàn)
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、測(cè)試
輸入一個(gè)格式錯(cuò)誤的身份證號(hào):
###
POST http://localhost:8080/member/register
Content-Type: application/json
{"idNo": "811111111111111111"}
輸出:
{
"code": -1,
"msg": "不是有效的身份證號(hào)"
}
輸入一個(gè)格式正確的身份證號(hào)(該身份證號(hào)是我隨機(jī)生成的):
###
POST http://localhost:8080/member/register
Content-Type: application/json
{"idNo": "12010319881011691X"}
輸出:
{
"code": 0,
"msg": "success"
}
三、總結(jié)
ConstraintValidator 是 javax validation 規(guī)范提供給我們的一個(gè)實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的接口。
像 hibernate.validator 就有很多這個(gè)接口的實(shí)現(xiàn),像我們常見的
- NotNullValidator
- MaxValidatorForMonetaryAmount
- MinValidatorForMonetaryAmount
等都是它的實(shí)現(xiàn)。以上代碼,參考 NotNullValidator 的實(shí)現(xiàn)。
到此這篇關(guān)于Javax Validation自定義注解進(jìn)行身份證號(hào)校驗(yàn)的文章就介紹到這了,更多相關(guān)Javax Validation自定義注解校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot項(xiàng)目javax.validation使用方法詳解
- java validation 后臺(tái)參數(shù)驗(yàn)證的使用詳解
- java使用Validation進(jìn)行數(shù)據(jù)校驗(yàn)的方式總結(jié)
- JAVA中通過Hibernate-Validation進(jìn)行參數(shù)驗(yàn)證
- JAVA中的字段校驗(yàn)(validation)
- 使用javax.validation.constraints對(duì)請(qǐng)求體進(jìn)行統(tǒng)一校驗(yàn)
- Java參數(shù)校驗(yàn)中validation和validator的區(qū)別詳解
- Java Validation Api實(shí)現(xiàn)原理解析
- Java Validation Api如何實(shí)現(xiàn)自定義注解
- Java使用validation攔截非法提交的數(shù)據(jù)的方法實(shí)現(xiàn)
相關(guān)文章
Java Character類的應(yīng)用場(chǎng)景
Java中的Character類提供了處理單個(gè)字符的靜態(tài)方法和實(shí)例方法,包括大小寫轉(zhuǎn)換、比較、分類等,它在處理用戶輸入、排序、查找和文本分類等場(chǎng)景中非常有用,下面就來詳細(xì)的介紹一下如何應(yīng)用,感興趣的可以了解一下2026-01-01
spring項(xiàng)目如何配置多數(shù)據(jù)源(已上生產(chǎn),親測(cè)有效)
這篇文章主要介紹了spring項(xiàng)目如何配置多數(shù)據(jù)源(已上生產(chǎn),親測(cè)有效),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java中編譯期異常和運(yùn)行期異常的區(qū)別解析
Java中的異常分為運(yùn)行期異常(RuntimeException)和編譯期異常(CheckedException),前者不強(qiáng)制處理,后者必須顯式處理,本文介紹Java中編譯期異常和運(yùn)行期異常的區(qū)別,感興趣的朋友一起看看吧2025-02-02
使用spring-boot-admin對(duì)spring-boot服務(wù)進(jìn)行監(jiān)控的實(shí)現(xiàn)方法
這篇文章主要介紹了使用spring-boot-admin對(duì)spring-boot服務(wù)進(jìn)行監(jiān)控的實(shí)現(xiàn)方法,需要的朋友可以參考下2018-02-02
JAVA浮點(diǎn)數(shù)計(jì)算精度損失底層原理與解決方案
本文主要介紹了JAVA浮點(diǎn)數(shù)計(jì)算精度損失底層原理與解決方案。具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02
SpringBoot3集成Calcite多數(shù)據(jù)源查詢的實(shí)戰(zhàn)示例小結(jié)
本文介紹了Spring Boot 3集成Apache Calcite實(shí)現(xiàn)多數(shù)據(jù)源查詢的實(shí)戰(zhàn)指南,本文通過實(shí)例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2026-02-02
java并發(fā)編程專題(一)----線程基礎(chǔ)知識(shí)
這篇文章主要介紹了java并發(fā)編程線程的基礎(chǔ)知識(shí),文中講解非常詳細(xì),幫助大家更好的學(xué)習(xí)JAVA并發(fā)編程,感興趣想學(xué)習(xí)JAVA的可以了解下2020-06-06

