> 文章列表 > 【Java实战】不会还有人用if else进行参数校验吧

【Java实战】不会还有人用if else进行参数校验吧

【Java实战】不会还有人用if else进行参数校验吧

当请求参数很多,几乎每一个参数都需要后端去兜底校验时,你还在写if else去判断参数是否为空吗??要校验为空的参数三四个还好,要是十几个,业务逻辑还没开始就写二三十行代码开始堆山了嘛,教给大家一个简单实用的方法,让大家不再在屎堆上堆代码。

注解

先来了解几个常用的注解

注解 含义 怎样使用
@NotBlank 字符串不为null且非空格长度至少为1 注解在String类型的参数上
@Null 必须为null 用于Long、Integer、BigDecimal基本数据类型上
@NotNull 必须不为null 用于Long、Integer、BigDecimal基本数据类型上
@NotEmpty 集合不为null且长度>0 用于集合校验
@AssertTrue 为true 用于Boolean类型上
@AssertFalse 为false 用于Boolean类型上
@Max 小于或等于某个数 一个字段的最大值为xx
@Min 大于或等于某个数 一个字段的最小值为xx
@Digits(integer=3, fraction=2) 整数和小数长度
@Pattern 正则匹配 手机号规则校验等
@Range(min=,max=) 数值类型范围
@Length 字符串长度范围 ----

实战篇

请求参数

BizRequestDTO

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;import javax.validation.Valid;
import java.util.Date;
import java.util.List;@Data
public class BizRequestDTO {/* 单据编号*/@NotBlank(message = "headId (单据编号)不能为空")private String headId;/* 金额*/@NotNull(message = "amount (金额)不能为空")private BigDecimal amount;/* 提单人*/@Validprivate EmpInfoDTO submitter;/* 分摊人列表*/@Validprivate List<EmpInfoDTO> expenseSharerList;
}

注解释义 @Valid

作用于对象,作用于集合 对象内校验方式:

    @Validprivate EmpInfoDTO submitter;

EmpInfoDTO

    /* 工号*/@NotBlank(message = "工号不能为空")private String workNo;/* 姓名*/@NotBlank(message = "姓名不能为空")private String nickName;

在代码中如何写?

引入依赖

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

引入一个工具类

import org.hibernate.validator.HibernateValidator;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;public class ValidatorUtils {private static final Validator DEFAULT_VALIDATOR;static {DEFAULT_VALIDATOR = Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory().getValidator();}public static <T> Set<ConstraintViolation<T>> validate(T bean) {return DEFAULT_VALIDATOR.validate(bean);}
}

实际应用

    public ResponseResult<String> checkExpenseParams(RequestParamDTO requestDTO) {Set<ConstraintViolation<TaeExpenseLineCheckRequestDTO>> result = ValidatorUtils.validate(requestDTO);// 错误信息输出StringBuilder resultInfo = new StringBuilder();result.forEach(validateResult -> resultInfo.append(validateResult.getMessage()).append("\\n"));if (StringUtils.isNotBlank(resultInfo)) {return ResponseResult.error(resultInfo.toString());}// 若为空则参数校验通过return ResponseResult.ok(null);}

输出示例

headId (单据编号)不能为空
amount (金额)不能为空

校验模式配置

Hibernate可以对校验模式的配置,支持快速失败,即在校验的过程中只要有一项不同过,剩余的参数就不再进行校验。默认使用的是全部校验完成后再返回,也就是在上面的例子中展示的那样。开启快速失败的具体的实现方式:

Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();

校验工具类

import org.hibernate.validator.HibernateValidator;import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.Validation;
import java.util.Set;public class ValidatorUtils {private static final Validator DEFAULT_VALIDATOR;private static final Validator FAST_VALIDATOR;static {DEFAULT_VALIDATOR = Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory().getValidator();FAST_VALIDATOR = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();}public static <T> Set<ConstraintViolation<T>> validate(T bean) {return DEFAULT_VALIDATOR.validate(bean);}public static <T> Set<ConstraintViolation<T>> fastValidate(T bean) {return FAST_VALIDATOR.validate(bean);}
}

快速校验使用方式同上,输出示例

headId (单据编号)不能为空

对象级联校验

包含级联对象的类

对象级联校验意味着,在一个对象中的属性可以包含另外一个校验对象,被级联的对象需要用@Valid注解修饰。上面也有给出🌰,本节再详细讲解一下。

例:

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;@Data
public class ValidatorWithDefineExtraModel {@NotBlank(message="姓名不能为空")private String name;@NotNull(message = "年龄不能为空")@Range(min=1, max=200, message = "年龄必须大于1小于200")private Integer age;@NotBlank(message="性别不能为空")@Pattern(regexp = "([FM])", message = "性别只能为F(女)或者M(男)")private String sex;@NotNull(message = "validatorModelExtra不能为空")@Validprivate ValidatorModelExtra validatorModelExtra;
}

被级联的对象

@Data
public class ValidatorModelExtra {@NotNull(message = "地址不能为空")@Length(max = 100, message = "地址长度不能大于100个字符")private String address;
}

输出示例:

地址不能为空