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

}

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

接口测试

校验结果为 成功


校验结果为 失败

相关推荐
Tirzano3 小时前
springsecurity自定义认证
spring boot·spring
bing_1586 小时前
简单工厂模式 (Simple Factory Pattern) 在Spring Boot 中的应用
spring boot·后端·简单工厂模式
天上掉下来个程小白6 小时前
案例-14.文件上传-简介
数据库·spring boot·后端·mybatis·状态模式
sjsjsbbsbsn8 小时前
Spring Boot定时任务原理
java·spring boot·后端
计算机毕设指导69 小时前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven
计算机-秋大田9 小时前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
小蒜学长10 小时前
医疗报销系统的设计与实现(代码+数据库+LW)
数据库·spring boot·学习·oracle·课程设计
橘猫云计算机设计11 小时前
基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!
java·数据库·spring boot·后端·python·计算机网络·毕设
小盼江11 小时前
水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 代码+开发文档+视频教程
vue.js·spring boot·ui
坚定信念,勇往无前12 小时前
Spring Boot中整合Flink CDC 数据库变更监听器来实现对MySQL数据库
数据库·spring boot·flink