美文网首页
自定义注解参数校验

自定义注解参数校验

作者: 帮我的鸵鸟盖个章 | 来源:发表于2020-11-18 15:31 被阅读0次

使用自定义注解校验参数,能使我们更加专注业务本身,而不用去写大量重复的校验,代码也更加简洁。

先自定义注解,并自定义校验实现

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.x.enums.CheckType;



/**
 * 常用校验  枚举
 */
@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<? extends javax.validation.Payload>[] payload() default {};
    
    /**
     * 校验实现
     * 实现ConstraintValidator接口,这是个泛型接口,泛型中第一个是自定义的注解,第二个是注解使用的类型。
     * 这里就是我们调用的字段校验方法
     */
    class CheckValidator implements ConstraintValidator<Check,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);
        }
    }
}

定义枚举,主要是不同字段+不同的验证规则。并实现真正的校验

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

import org.apache.commons.lang3.StringUtils;

/**
 * 常用校验类型
 */
public enum CheckType {
    /**
     * 手机号验证枚举
     */
    MOBILE("Mobile", "手机", "^1[0-9]{10}$"),

    SHOT_DATE("Date", "短日期格式", "yyyyMMdd"),
    TOOLOOG_DATE("Date", "短日期格式", "yyyyMMddHHmmssSSS"),
    DATE("Date", "常用时间格式", "yyyy-MM-dd HH:mm:ss"),
    /**
     * 请求流水号验证枚举
     */
    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;
    }

    public static CheckType with(String value) {
        for (CheckType type : CheckType.values()) {
            if (type.value.equalsIgnoreCase(value)) {
                return type;
            }
        }
        return null;
    }

    /**
     * 校验方法
     * 验证传入的枚举值,是否符合规则
     * @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);
    }
}

定义一个dto,对里面的字段使用自己的注解

package com.mayn.external.dto;

import java.io.Serializable;

import javax.validation.constraints.NotBlank;
import com.x.annotation.Check;
import com.x.enums.CheckType;

import lombok.Data;

@SuppressWarnings("serial")
@Data
public class UserDto implements Serializable{
    /**
     * 32位流水号
     */
    @Check(type=CheckType.REQUEST_NO,message="请求流水号格式错误")
    private String requestNo;
    
    @Check(type=CheckType.TOOLOOG_DATE,message="时间戳格式不正确,格式:yyyyMMddHHmmssSSS")
    @NotBlank(message="时间戳不能为空")
    private String timestamp;           
            
    
}

controller测试

@RestController
@RequestMapping("/valid")
public class TestValidController {
    @PostMapping("/login")
    public Object test(@RequestBody @Valid UserDto user) {
        return request.toString();
    }
}

@Valid注解会对UserDto中加了Check的字段进行校验。

相关文章

网友评论

      本文标题:自定义注解参数校验

      本文链接:https://www.haomeiwen.com/subject/dxuciktx.html