自定义注解实现参数校验(通过@Valid触发)

实现对入参校验逻辑,
利用@Constraint绑定实现了ConstraintValidator接口的方法
注解Check.java

package com.snail.redisMemory.annotaion;
import com.snail.redisMemory.paramcheck.CheckType;

import java.lang.annotation.*;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * 常用校验  枚举
 */
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = Check.CheckValidator.class)// 注意这里,指出了自定义的校验方法
public @interface Check {

    String message() default ""; // 自定义异常返回信息

    CheckType type(); // 自定义校验字段

    Class[] groups() default {};

    Class.validation.Payload>[] payload() default {};

    /**
     * 校验实现
     * 实现ConstraintValidator接口,这是个泛型接口,泛型中第一个是自定义的注解,第二个是注解使用的类型。
     * 这里就是我们调用的字段校验方法
     */
    class CheckValidator implements ConstraintValidator,Object>{
        private CheckType type;

        @Override
        public void initialize(Check constraintAnnotation) {
            this.type=constraintAnnotation.type();
        }

        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            return CheckType.validate(type,value);
        }
    }
}

CheckType.java

package com.snail.redisMemory.paramcheck;

import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

import org.springframework.util.StringUtils;

/**
 * 常用校验类型
 */
public enum CheckType {
    TOOLOOG_DATE("Date", "短日期格式", "yyyyMMddHHmmssSSS"),
    REQUEST_NO("RequestNo", "请求流水号", "^[0-9a-zA-Z]{32}");

    public String value;
    public String label;
    public String regular;

    private CheckType(String value, String label, String regular) {
        this.value = value;
        this.label = label;
        this.regular = regular;
    }

    /**
     * 校验方法
     * 验证传入的枚举值,是否符合规则
     * @param type
     * @return true:验证成功;false:验证失败
     */
    public static boolean validate(CheckType type, Object obj) {
        if (null == obj || null == type) {
            //空不校验
            return true;
        }
        if (!(obj instanceof String)) {
            //不是String 返回false
            return false;
        }
        String str = obj.toString();
        if (StringUtils.isEmpty(str)) {
            //空字符串不校验
            return true;
        }
        //日期格式不适用正则
        if ("Date".equals(type.value)) {
            SimpleDateFormat sdf = new SimpleDateFormat(type.regular);
            try {
                sdf.parse(str);
            } catch (Exception e) {
                return false;
            }
            return true;
        }
        //使用正则校验
        return Pattern.matches(type.regular, str);
    }
}

UserDto

package com.snail.redisMemory.paramcheck;

import java.io.Serializable;

import com.snail.redisMemory.annotaion.Check;
import lombok.Data;

@SuppressWarnings("serial")
@Data
public class UserDto implements Serializable{
    /**
     * 编码
     */
    @Check(type=CheckType.REQUEST_NO,message="编码格式错误")
    private String requestNo;

    @Check(type=CheckType.TOOLOOG_DATE,message="时间戳格式不正确,格式:yyyyMMddHHmmssSSS")
    private String timestamp;
}

最后写post方法调用

 @PostMapping("/check")
    public Object test(@RequestBody @Valid UserDto user) {
        return "";
    }

调用结果
自定义注解实现参数校验(通过@Valid触发)_第1张图片
涉及依赖,其中若不引用hibernate-validator,不会触发校验逻辑


			org.springframework.boot</groupId>
			spring-boot-starter-aop</artifactId>
		</dependency>

		
			javax.validation</groupId>
			validation-api</artifactId>
			2.0.1.Final</version>
		</dependency>
		
			org.hibernate</groupId>
			hibernate-validator</artifactId>
			6.0.15.Final</version>
		</dependency>

		
			org.projectlombok</groupId>
			lombok</artifactId>
			1.18.22</version>
		</dependency>

你可能感兴趣的:(AOP,Aspect,java)