看了前面的几篇文章,想必大家对注解已经有了一些认识,工作中应该可以简单的使用注解了。这几天做项目又碰到了一个校验的问题,顺便有写了一个简单的注解,和大家分享下。
前文我也提到过,在Spring框架中,controller 中大家使用注解接收json参数,对参数一般会加上注解,入@NotNull等,这样参数进入方法的时候就已经进行了校验。
相关的jar包中封装了不少校验规则,基本上能服务与大部分校验。但是偶尔突然想拓展了怎么办呢?别着急,这些校验机制都是留有接口可以让使用者自行拓展的,就好像spring框架一般,许多的实现都可以自行实现。
下面我们来实现一个身份证号码的校验。
先定义一个注解,写法的话都是这种模式,想要利用别人的校验处理的代码,自然要符合原作者的规则。
package com.example.demoproject.valid;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ConstraintImpl.class)
public @interface ValidIDCard {
String message();
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
下面实现注解的校验,需要实现一个接口 ConstraintValidator,代码如下
package com.example.demoproject.valid;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class ConstraintImpl implements ConstraintValidator<ValidIDCard,Object> {
private static final String IDCard18 = "[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]";
private static final String IDCard15 = "[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}";
@Override
public void initialize(ValidIDCard constraintAnnotation) {
// 获取注解值中的value,如果有需要的话可以进行处理,比如Max,Min 就需要
System.out.println("校验身份证号初始化~~~");
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
Pattern pattern ;
if(o instanceof String){
String str = (String)o;
if(str.length()==18){
pattern = Pattern.compile(IDCard18);
return pattern.matcher(str).matches();
}
if(str.length()==15){
pattern = Pattern.compile(IDCard15);
return pattern.matcher(str).matches();
}
}
return false;
}
}
这样在方法中就实现了一个正则的校验。那好,我们来写一个方法测试下。
创建一个对象
package com.example.demoproject.dto;
import com.example.demoproject.valid.ValidIDCard;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class ValidDTO {
@NotNull(message = "名称不能为空")
String name;
@ValidIDCard(message = "身份证号格式不对~")
String idCard;
String age;
}
下面写一个方法测试:
@PostMapping(value = "test-valid")
public String testValid(@RequestBody @Valid ValidDTO validDTO){
return JSON.toJSONString(validDTO);
}
请求参数中如果身份证号无法匹配正则,自然会报错,这个错误没有捕获处理,直接贴出来了哈~
"errors": [
{
"codes": [
"ValidIDCard.validDTO.idCard",
"ValidIDCard.idCard",
"ValidIDCard.java.lang.String",
"ValidIDCard"
],
"arguments": [
{
"codes": [
"validDTO.idCard",
"idCard"
],
"arguments": null,
"defaultMessage": "idCard",
"code": "idCard"
}
],
"defaultMessage": "身份证号格式不对~",
"objectName": "validDTO",
"field": "idCard",
"rejectedValue": "341282199175",
"bindingFailure": false,
"code": "ValidIDCard"
}
],
特别深入的就不说了,今天写这个主要是为了两个字--实用!希望能对大家有帮助。