身份证号码,格式校验:@IdCard(Validation + Hutool)

目标

自定义一个用于校验 身份证号码 格式的注解@IdCard,能够和现有的 Validation 兼容,使用方式和其他校验注解保持一致(使用 @Valid 注解接口参数)。

校验逻辑

有效格式

符合国家标准。

公民身份号码按照GB11643-1999《公民身份号码》国家标准编制,由18位数字组成:前6位为行政区划代码,第7至14位为出生日期码,第15至17位为顺序码,第18位为校验码。

不校验非空

身份证号码注解,校验的是格式;不校验是否为空(null 或 空字符串)。如果身份证号码为空,此注解校验是可以通过的;

校验非空,使用注解 @NotEmpty;根据业务逻辑来确定,身份证号码是否需要判断非空。

校验格式的工具:Hutool

使用Hutool提供的身份证格式校验方法。

注意,Hutool 校验身份证格式,忽略X的大小写;也就是,大小写的X,都认为表达的是罗马数字十

依赖

  1. Validation
  2. Hutool

Validation:

xml 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

Hutool:

xml 复制代码
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>

核心代码

需要自定义的内容,包含两个部分:

  1. 注解@IdCard
  2. 校验器IdCardValidator

注解:@IdCard

java 复制代码
package com.example.core.validation.idcard;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * 身份证号码。字符串必须是格式正确的身份证号码。
 * <p>
 * {@code null} 或 空字符串,是有效的(能够通过校验)。
 * <p>
 * 支持的类型:字符串
 *
 * @author songguanxun
 * @since 1.0
 */
@Target({FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = IdCardValidator.class)
public @interface IdCard {

    /**
     * @return the error message template
     */
    String message() default "身份证号码,格式错误";

    /**
     * @return the groups the constraint belongs to
     */
    Class<?>[] groups() default {};

    /**
     * @return the payload associated to the constraint
     */
    Class<? extends Payload>[] payload() default {};

}

校验器:IdCardValidator

java 复制代码
package com.example.core.validation.idcard;

import cn.hutool.core.util.IdcardUtil;
import com.example.core.validation.ResetMessageUtil;
import org.springframework.util.ObjectUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * 身份证号码,格式校验器
 */
public class IdCardValidator implements ConstraintValidator<IdCard, String> {

    @Override
    public void initialize(IdCard constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }


    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (ObjectUtils.isEmpty(value)) {
            return true;
        }

        if (value.contains(" ")) {
            ResetMessageUtil.reset(context, "身份证号码,格式错误:不能包含空格");
            return false;
        }

        return IdcardUtil.isValidCard(value);
    }

}

使用

@IdCard 放在需要校验格式的 身份证号码 字段上。

java 复制代码
package com.example.web.response.model.param;

import com.example.core.validation.idcard.IdCard;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
@Schema(name = "新增用户Param")
public class UserAddParam {
    
    // 其他字段

    @IdCard
    @Schema(description = "身份证号码", example = "110101202301024130")
    private String idCard;

}

补充代码

ResetMessageUtil:重置提示信息工具类

java 复制代码
package com.example.core.validation;

import javax.validation.ConstraintValidatorContext;

/**
 * 参数校验 - 重置提示信息工具类
 */
public class ResetMessageUtil {

    /**
     * 重置提示信息
     */
    public static void reset(ConstraintValidatorContext context, String message) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
    }

}

校验效果

校验工具类(Hutool),测试

对Hutool提供的身份证校验方法,进行测试。

java 复制代码
package com.example;

import cn.hutool.core.util.IdcardUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

/**
 * 身份证号码校验测试(使用Hutool)
 */
@Slf4j
public class IdCardHutoolTest {

    @Test
    void test() {
        test("110101202301024130");
        test("11010120230102857X");
        test("11010120230102857x");
        test("110101202301024130啊啊啊啊");
    }


    private void test(String idCard) {
        boolean validCard = IdcardUtil.isValidCard(idCard);
        log.info("是否为身份证号码格式:{} = {}", idCard, validCard);
    }

}

能够正确校验身份证格式。

接口测试

校验结果为 成功


校验结果为 失败

相关推荐
kylinxjd19 分钟前
spring boot发送邮件
java·spring boot·后端·发送email邮件
杨荧28 分钟前
【JAVA开源】基于Vue和SpringBoot的旅游管理系统
java·vue.js·spring boot·spring cloud·开源·旅游
2401_857439694 小时前
Spring Boot新闻推荐系统:用户体验优化
spring boot·后端·ux
进击的女IT4 小时前
SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS
java·spring boot·后端
杨半仙儿还未成仙儿6 小时前
Spring框架:Spring Core、Spring AOP、Spring MVC、Spring Boot、Spring Cloud等组件的基本原理及使用
spring boot·spring·mvc
一 乐6 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
IT学长编程8 小时前
计算机毕业设计 二手图书交易系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·二手图书交易系统
艾伦~耶格尔9 小时前
Spring Boot 三层架构开发模式入门
java·spring boot·后端·架构·三层架构
man20179 小时前
基于spring boot的篮球论坛系统
java·spring boot·后端
Java探秘者9 小时前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea