身份证号码,格式校验:@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);
    }

}

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

接口测试

校验结果为 成功


校验结果为 失败

相关推荐
wb043072013 小时前
使用 Java 开发 MCP 服务并发布到 Maven 中央仓库完整指南
java·开发语言·spring boot·ai·maven
nbwenren4 小时前
Springboot中SLF4J详解
java·spring boot·后端
helx825 小时前
SpringBoot中自定义Starter
java·spring boot·后端
rleS IONS6 小时前
SpringBoot获取bean的几种方式
java·spring boot·后端
R***z1017 小时前
Spring Boot 整合 MyBatis 与 PostgreSQL 实战指南
spring boot·postgresql·mybatis
赵丙双8 小时前
spring boot AutoConfiguration.replacements 文件的作用
java·spring boot
计算机学姐9 小时前
基于SpringBoot的兴趣家教平台系统
java·spring boot·后端·spring·信息可视化·tomcat·intellij-idea
bearpping10 小时前
Spring Boot + Vue 全栈开发实战指南
vue.js·spring boot·后端
__土块__11 小时前
一次 Spring Boot 自动装配机制源码走读:从误用 @Component 到理解 Bean 生命周期
spring boot·源码分析·自动装配·bean生命周期·@configuration·configurationclasspostprocessor·cglib代理
回到原点的码农13 小时前
Spring Boot 3.3.4 升级导致 Logback 之前回滚策略配置不兼容问题解决
java·spring boot·logback