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 接口的類來(lái)實(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中通過(guò)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)文章
Spring強(qiáng)大事務(wù)兼容數(shù)據(jù)庫(kù)多種組合解決業(yè)務(wù)需求
這篇文章主要為大家介紹了Spring強(qiáng)大事務(wù)兼容數(shù)據(jù)庫(kù)多種組合解決業(yè)務(wù)需求示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
springboot如何使用logback-spring配置日志格式,并分環(huán)境配置
這篇文章主要介紹了springboot如何使用logback-spring配置日志格式,并分環(huán)境配置的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
論Java Web應(yīng)用中調(diào)優(yōu)線程池的重要性
這篇文章主要論述Java Web應(yīng)用中調(diào)優(yōu)線程池的重要性,通過(guò)了解應(yīng)用的需求,組合最大線程數(shù)和平均響應(yīng)時(shí)間,得出一個(gè)合適的線程池配置2016-04-04
Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn)
這篇文章主要介紹了Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Spring延遲Bean初始化的實(shí)現(xiàn)示例
延遲初始化也叫做惰性初始化,指不提前初始化Bean,而是只有在真正使用時(shí)才創(chuàng)建及初始化Bean,本文主要介紹了Spring延遲Bean初始化的實(shí)現(xiàn)示例,感興趣的可以了解一下2024-06-06

