Javax Validation自定义注解进行身份证号校验
作者:matrixlzp
一、场景分析
我们使用 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]$)$"; 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、在实体类中使用自定义注解
package com.study.member.entity; import com.study.annotations.IdCheck; import lombok.Data; @Data public class Member { // 自定义注解 @IdCheck private 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自定义注解进行身份证号校验的文章就介绍到这了,更多相关Javax Validation自定义注解校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!