java注解闲聊——自定义参数校验注解

看了前面的几篇文章,想必大家对注解已经有了一些认识,工作中应该可以简单的使用注解了。这几天做项目又碰到了一个校验的问题,顺便有写了一个简单的注解,和大家分享下。

前文我也提到过,在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"
        }
    ],

特别深入的就不说了,今天写这个主要是为了两个字--实用!希望能对大家有帮助。

                       

no sacrifice no victory!!!

猜你喜欢

转载自blog.csdn.net/zsah2011/article/details/106677913