借助swagger注解 对参数进行优雅校验

一.通过swagger注解定义校验规则

swagger注解再项目中常常用到,我们可以通过定义value值来实现参数校验

1.定义工具类方法

package com.ruoyi.common.verily;

import com.ruoyi.common.exception.ServiceException;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.List;


public class ApiVerify {
    /**
     * 依据注解进行入参校验
     * @param bizDesc       校验业务描述
     * @param obj           入参DTO
     * @param bInsert       是否是新增进行全变量检查
     * @param noEmptyFields 本次检查不容许为空的属性列表,用,分隔
     * @return void
     */
    public static void verifyApiModelProperty(String bizDesc, Object obj, boolean bInsert, String noEmptyFields) {
        if (null == obj) {
            return;
        }
        if (obj instanceof List) {
            for (Object o : (List<?>) obj) {
                for (Field field : o.getClass().getDeclaredFields()) {
                    verifyApiFieldProperty(bizDesc, o, field, bInsert, noEmptyFields);
                }
            }
            return;
        }
        for (Field field : obj.getClass().getDeclaredFields()) {
            verifyApiFieldProperty(bizDesc, obj, field, bInsert, noEmptyFields);
        }
    }


    /**
     * 依据注解进行入参数据域校验
     * @param bizDesc       校验业务描述
     * @param obj           入参DTO
     * @param field         入参数据域
     * @param bInsert       是否是插入进行全变量检查
     * @param noEmptyFields 本次检查不容许为空的属性列表,用,分隔
     * @return void
     */
    private static void verifyApiFieldProperty(String bizDesc, Object obj, Field field, boolean bInsert, String noEmptyFields)  {
        if (null == field) {
            return;
        }
        if (StringUtils.isBlank(noEmptyFields)) {
            noEmptyFields = "";
        } else {
            noEmptyFields = "," + noEmptyFields + ",";
        }

        Object oValue = null;
        String fName = "";
        try {
            field.setAccessible(true);
            fName = field.getName();
            oValue = field.get(obj);
        } catch (Exception ex) {
            return;
        }
        //取得注解的内容
        ApiModelProperty property = field.getAnnotation(ApiModelProperty.class);
        if (null == property) {
            return;
        }
        //分析注解信息
        String propValue = property.value();
        VerifyDTO verifyProp = getVerifyProper(propValue);
        if (null == verifyProp) {
            return;
        }
        String ename = verifyProp.getEname();
        String cname = verifyProp.getCname();
        int maxLen = verifyProp.getMaxLen();
        int minLen = verifyProp.getMinLen();

        //空值校验
        String sName = "," + fName + ",";
        boolean bVerifyEmpty = false;
        //修改noEmptyFields.indexOf(sName) >= 0  原来是>,改成>=
//        if (noEmptyFields.indexOf(sName) >= 0 || (bInsert && minLen > 0)) {
        if (noEmptyFields.contains(sName) || (bInsert && minLen > 0)) {
            bVerifyEmpty = true;
        }
        if (null == oValue || StringUtils.isBlank(oValue.toString())) {
            if (bVerifyEmpty) {
                throw new ServiceException(bizDesc + " " + cname + "[" + ename + "]不能为空");
            }
            return;
        }

        //最大长度校验
        String strValue = null;
        if (oValue instanceof String) {
            strValue = oValue.toString();
            if (maxLen > 0 && strValue.length() > maxLen) {
                //修改提示,原来是minLen,改成maxLen
                throw new ServiceException(bizDesc + " " + cname + "[" + ename + "]长度不能超过"+maxLen);
            }
        }
    }

    /**
     * 依据数据域注解分析校验信息,cn=黑名单标志|en=bklsFlag|minlen=0|maxLen=3|type=date
     * @param expr 注解表达式
     * @return VerifyDTO 校验信息
     */
    private static VerifyDTO getVerifyProper(String expr) {
        VerifyDTO res = null;
        if (StringUtils.isBlank(expr)) {
            return null;
        }
        String tmpExpr;
        int iPos;
        String fKey, fValue;
        while (!"".equals(expr)) {
            iPos = expr.indexOf("|");
            if (iPos < 0) {
                tmpExpr = expr;
                expr = "";
            } else {
                tmpExpr = expr.substring(0, iPos);
                expr = expr.substring(1 + iPos);
            }
            iPos = tmpExpr.indexOf("=");
            if (iPos < 0) {
                continue;
            }
            fKey = tmpExpr.substring(0, iPos);
            fValue = tmpExpr.substring(1 + iPos);
            fKey = fKey.trim();
            fValue = fValue.trim();
            if (null == res) {
                res = new VerifyDTO();
            }
            res.setProp(fKey, fValue);
        }
        return res;
    }
}

package com.ruoyi.common.verily;

import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;


public class VerifyDTO implements Serializable {
    private String ename;
    private String cname;
    private int maxLen;
    private int minLen;

    public String getEname() {
        return ename;
    }

    @Override
    public String toString() {
        return "中文描述:" + cname + "|"
                + "属性名:" + ename + "|"
                + "最大长度:" + maxLen + "|"
                + "最小长度:" + minLen + "";
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getCname() {
        return cname;
    }

    public void setProp(String name, String val) {
        if (StringUtils.isBlank(name) || StringUtils.isBlank(val)) {
            return;
        }
        name = name.toLowerCase().trim();
        if ("cn".equals(name)) {
            setCname(val);
            return;
        }
        if ("en".equals(name)) {
            ename = val;
            return;
        }
        int intVal = 0;
        try {
            intVal = Integer.parseInt(val);
        } catch (Exception ex) {
            return;
        }
        if ("minlen".equals(name)) {
            minLen = intVal;
            return;
        }
        if ("maxlen".equals(name)) {
            maxLen = intVal;
            return;
        }
    }

    public void setCname(String cname) {
        if (StringUtils.isBlank(cname)) {
            cname = "";
        }
        int iPos = cname.indexOf(" ");
        if (iPos < 0) {
            iPos = cname.indexOf("(");
        }
        if (iPos < 0) {
            iPos = cname.indexOf("(");
        }
        if (iPos < 0) {
            iPos = cname.indexOf("-");
        }
        if (iPos < 0) {
            iPos = cname.indexOf(" ");
        }
        if (iPos > 0) {
            cname = cname.substring(0, iPos);
        }
        this.cname = cname;
    }

    public int getMaxLen() {
        return maxLen;
    }

    public void setMaxLen(int maxLen) {
        this.maxLen = maxLen;
    }

    public int getMinLen() {
        return minLen;
    }

    public void setMinLen(int minLen) {
        this.minLen = minLen;
    }
}

2.测试

借助swagger注解 对参数进行优雅校验_第1张图片
借助swagger注解 对参数进行优雅校验_第2张图片
借助swagger注解 对参数进行优雅校验_第3张图片

二.常用注解校验

1 Maven依赖

 <!--第一种方式导入校验依赖-->
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>2.0.1.Final</version>
    </dependency>
    <!--第二种方式导入校验依赖-->
    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
    </dependency>

2 值校验
2.1 @Null注解
被注解的元素必须为null

@Null(message = "必须为null")
private String username;

2.2 @NotNull注解
被注解的元素必须不为null

@NotNull(message = "必须不为null")
private String username;

2.3 @NotBlank注解
验证注解的元素值不为空(不为null、去除首位空格后长度为0) ,并且类型为String。

@NotBlank(message = "必须不为空")
private String username;

2.4 @NotEmpty注解
验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) ,并且类型为String。

@NotEmpty(message = "必须不为null且不为空")
private String username;

2.5 @AssertTrue注解
被注解的元素必须为true,并且类型为boolean。

@AssertTrue(message = "必须为true")
private boolean status;

2.6 @AssertFalse注解
被注解的元素必须为false,并且类型为boolean。

@AssertFalse(message = "必须为false")
private boolean status;

3 范围校验
3.1 @Min注解
被注解的元素其值必须大于等于最小值,并且类型为int,long,float,double。

@Min(value = 18, message = "必须大于等于18")
private int age;

3.2 @Max注解
被注解的元素其值必须小于等于最小值,并且类型为int,long,float,double。

@Max(value = 18, message = "必须小于等于18")
private int age;

3.3 @DecimalMin注解
验证注解的元素值大于等于@DecimalMin指定的value值,并且类型为BigDecimal。

@DecimalMin(value = "150", message = "必须大于等于150")
private BigDecimal height;

3.4 @DecimalMax注解
验证注解的元素值小于等于@DecimalMax指定的value值 ,并且类型为BigDecimal。

@DecimalMax(value = "300", message = "必须大于等于300")
private BigDecimal height;

3.5 @Range注解
验证注解的元素值在最小值和最大值之间,并且类型为BigDecimal,BigInteger,CharSequence,byte,short,int,long。

@Range(max = 80, min = 18, message = "必须大于等于18或小于等于80")
private int age;

3.6 @Past注解
被注解的元素必须为过去的一个时间,并且类型为java.util.Date。

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Past(message = "必须为过去的时间")
private Date createDate;

3.7 @Future注解
被注解的元素必须为未来的一个时间,并且类型为java.util.Date。

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Future(message = "必须为未来的时间")
private Date createDate;

4 长度校验
4.1 @Size注解
被注解的元素的长度必须在指定范围内,并且类型为String,Array,List,Map。

@Size(max = 11, min = 7, message = "长度必须大于等于7或小于等于11")
private String mobile;

4.2 @Length注解
验证注解的元素值长度在min和max区间内 ,并且类型为String。

@Length(max = 11, min = 7, message = "长度必须大于等于7或小于等于11")
private String mobile;

5 格式校验
5.1 @Digits注解
验证注解的元素值的整数位数和小数位数上限 ,并且类型为float,double,BigDecimal。

@Digits(integer=3,fraction = 2,message = "整数位上限为3位,小数位上限为2位")
private BigDecimal height;

5.2 @Pattern注解
被注解的元素必须符合指定的正则表达式,并且类型为String。

@Pattern(regexp = "\\d{11}",message = "必须为数字,并且长度为11")
private String mobile;

5.3 @Email注解
验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式,类型为String。

 @Email(message = "必须是邮箱")
private String email;

————————————————

部分参考:https://blog.csdn.net/qq_38974638/article/details/115396937

你可能感兴趣的:(java)