在我们日常工作中,会有这样的需求,假如前端新增、修改数据时,后端要针对身份证号格式进行校验 ,但是框架有没有提供现成的关于身份证号校验的注解,如果写在业务层里,无异于会增加代码的复杂度,综上考虑,使用自定义注解是比较方便且高效的
注解代码:
@Documented @Constraint(validatedBy = IdCardValidator.class) @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface IdCard { String message() default "身份证号格式不正确"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
手机号校验业务处理:
public class IdCardValidator implements ConstraintValidator<IdCard, String> { private static final Pattern PATTERN = Pattern.compile("^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9Xx])$"); private static final Map<Integer, String> VERIFY_CODE = new HashMap<Integer, String>() { private static final long serialVersionUID = 2725763670639092743L; { put(0, "1"); put(1, "0"); put(2, "X"); put(3, "9"); put(4, "8"); put(5, "7"); put(6, "6"); put(7, "5"); put(8, "4"); put(9, "3"); put(10, "2"); } }; @Override public void initialize(IdCard constraintAnnotation) { // 初始化方法,通常不需要做额外的处理 } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (value == null || value.isEmpty()) { return true; // 允许空值通过校验,根据实际需求可以改为false } Matcher matcher = PATTERN.matcher(value); if (!matcher.matches()) { return false; // 身份证号格式不正确 } return isValidChineseID(value); // 校验身份证号的校验码 } /** * 判断身份证号格式是否正确 * @param id id * @return boolean */ public static boolean isValidChineseID(String id) { if (!PATTERN.matcher(id).matches()) { return false; } // 提取身份证的前17位数字 String idNumber = id.substring(0, 17); // 提取身份证的第18位数字或字母 String lastNumber = id.substring(17, 18); // 计算身份证校验码 int sum = 0; for (int i = 0; i < idNumber.length(); i++) { sum += Integer.parseInt(String.valueOf(idNumber.charAt(i))) * (Math.pow(2, (idNumber.length() - i)) % 11); } // 计算出的值对应的校验码 String verifyCode = VERIFY_CODE.get(sum % 11); // 校验码进行比较 return lastNumber.toUpperCase().equals(verifyCode); } }
实体类使用:
@Data public class EventRegistrationAddParam { @ApiModelProperty(value = "身份证号", example = "身份证号") @NotBlank(message = "身份证号不能为空") @Length(max = 20, message = "身份证号过长,不能超过20个字符") @IdCard private String idNumber; }
控制层:
@PostMapping("add") @ApiOperation(value = "新增活动报名", notes = "新增活动报名") public void add(@RequestBody @Validated EventRegistrationAddParam param) { charitableOrgBusinessWriteService.addEventRegistration(param, getCurUserAccount()); }