目录
3.非空校验注解 @NotNull、@NotEmpty、@NotBlank的区别和运用
1.使用场景
方法体在根据参数进行逻辑处理时,尝尝需要对参数进行校验,一些简单的校验可以使用Validator校验方法。
2.常用注解
@Null 限制必须为null
@NotNull 限制必须不能为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为一个不超过指定大小值的数字
@DecimalMin(value) 限制必须为一个不低于指定大小值的数字
@Digits(integert,fraction) 限制必须为一个小数,且整数部分位数不能超过integer,小数部分位数不能超过fraction
@Futrue 限制必须为一个将来的日期
@Past 限制必须为一个过去的日期
@Max(value) 限制必须为一个不超过指定大小值的数字
@Min(value) 限制必须为一个不低于指定大小值的数字
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须处在max和min的值之间
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0,集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null,且去除首位空格后长度不为0),不同于@NotEmpty,@NotBlank只适用于字符串的校验且在校验时会去除字符串的空格
@Email 验证值是否为邮箱,也可以通过正则表达式和flag指定自定义的email格式
@Length 限制字符串参数长度
@Range 限制数值类型或者字符串在指定范围
@URL 对URL地址进行验证
3.非空校验注解 @NotNull、@NotEmpty、@NotBlank的区别和运用
@NotNull 常用在数据类型为Long,Integer的基础数据类型上,可以配合@Size、@Max、@Min对数值进行大小的控制。
@ApiModelProperty(value = "编号")
@NotNull(message = "编号不能为空")
@JsonFormat(shape = Shape.STRING)
private Long id;
@ApiModelProperty(value = "价格")
@NotNull(message = "价格不能为空")
@Min(value = 100, message = "价格不能低于100")
@Max(value = 5000, message = "价格不能超过5000")
private Integer price;
@ApiModelProperty(value = "数量")
@NotNull(message = "数量不能为空")
@Size(min = 10, max = 50, message = "数量必须不低于10不超过50")
private Integer num;
@NotEmpty
该注解只能应用于char可读序列(可简单理解为String对象),colleaction,map,array上,因为该注解要求的是对象不为null且size>0,所以只有上述对象是拥有size属性的,而Integer,Long等基础对象包装类没有该属性。
常用在集合类和数组类型上,也可以配合@Size进行大小的控制。
@ApiModelProperty(value = "材料保存列表", required = true)
@NotEmpty(message = "存货清单列表不能为空")
@Size(min = 1, message = "至少需要一条数据")
private List<MaterialAcceptanceItemsSaveVo> itemsSaveList;
@NotBlank 只用于String数据类型上,可以和@Len配合使用限制字符长度。
@ApiModelProperty(value = "供应商", required = true)
@NotBlank(message = "供应商不能为空")
@Len(min = 1, max = 500)
private String provider;
@ApiModelProperty(value = "发票号", required = true)
@Len(min = 0, max = 250)
private String invoiceNo;
4.使用示例
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
实体类
package com.example.demo.domain;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import lombok.Data;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author linaibo
* @version 1.0
* Create by 2022/12/4 14:13
*/
@Data
@ExcelIgnoreUnannotated
public class Teacher {
//id
// @ExcelProperty(value = "id")
@NotNull(message = "id不能为空")
private int id;
//名字
@ContentFontStyle(color = 10,fontHeightInPoints=12)
@ExcelProperty(value = "名字")
@Pattern(regexp = "1|2", message = "只能填写1或者2中的一个")
@NotBlank(message = "名字不能为空")
private String name;
//邮箱
@ExcelProperty(value = "邮箱")
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
//年龄
@ExcelProperty(value = "年龄")
@NotNull(message = "年龄不能为空")
@Max(value = 20,message = "必须小于20")
private int age;
//是否结婚
@ExcelProperty(value = "是否结婚")
@AssertTrue(message = "是否结婚必须是是")
private boolean isMarry;
//是否有孩子
@ExcelProperty(value = "是否有孩子")
@AssertFalse(message = "是否结婚必须是否")
private boolean isChilden;
//体重
@ExcelProperty(value = "体重")
@NotNull(message = "体重不能为空")
@DecimalMax(value = "100", message = "体重不能超过100")
private BigDecimal weight;
//身高
@ExcelProperty(value = "身高")
@NotNull(message = "身高不能为空")
@DecimalMin(value = "170", message = "身高不能低于170")
private BigDecimal height;
//出生日期
@ExcelProperty(value = "出生日期")
@NotNull(message = "出生日期不能为空")
@Past(message = "出生日期必须为过去的日期")
private Date date1;
//死亡日期
@ExcelProperty(value = "死亡日期")
@NotNull(message = "死亡日期不能为空")
@Future(message = "死亡日期必须为将来的日期")
private Date date2;
}
校验逻辑
package com.example.demo.service.impl;
import cn.hutool.core.date.DateUtil;
import com.example.demo.domain.Teacher;
import com.example.demo.service.TeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.math.BigDecimal;
import java.util.Set;
/**
* @author linaibo
* @version 1.0
* Create by 2022/12/4 14:42
*/
@Service
public class TeacherServiceImpl implements TeacherService {
@Autowired
private Validator validator;
public void check() {
Teacher teacher = new Teacher();
teacher.setId(12);
teacher.setAge(25);
teacher.setDate1(DateUtil.parse("2023-11-01","yyyy-MM-dd"));
teacher.setDate2(DateUtil.parse("2020-11-12","yyyy-MM-dd"));
teacher.setEmail("1245783");
teacher.setChilden(true);
teacher.setMarry(false);
teacher.setHeight(new BigDecimal(160));
teacher.setWeight(new BigDecimal(150));
teacher.setName("小琳");
// teacher.setId(12);
// teacher.setAge(25);
// teacher.setDate1(DateUtil.parse("2020-11-01","yyyy-MM-dd"));
// teacher.setDate2(DateUtil.parse("2023-11-12","yyyy-MM-dd"));
// teacher.setEmail("1245783@qq.com");
// teacher.setChilden(false);
// teacher.setMarry(true);
// teacher.setHeight(new BigDecimal(170));
// teacher.setWeight(new BigDecimal(100));
// teacher.setName("小琳");
System.out.println(teacher);
Set<ConstraintViolation<Teacher>> validate = validator.validate(teacher);
// validate.forEach(item -> System.out.println(item.getMessage()));
System.out.println(validate);
throw new ConstraintViolationException(validate);
}
}
校验的结果得到一个set集合,一般是抛出异常,使用ConstraintViolationException(validate)直接对结果集进行抛出,结果如下
javax.validation.ConstraintViolationException: isChilden: 是否结婚必须是否, isMarry: 是否结婚必须是是, height: 身高不能低于170, date2: 死亡日期必须为将来的日期, email: 邮箱格式不正确, date1: 出生日期必须为过去的日期, weight: 体重不能超过100
也可以循环取得具体的信息,拼接之后直接抛出。
示例1:
@Autowired
private Validator validator;
public StorageFee calculateBasicStorageFee(StorageChargeDto dto) {
log.info("calculateBasicStorageFee入参信息,dto={}", JSON.toJSONString(dto));
StorageFee fee = new StorageFee();
//校验参数是否为空
BeanValidators.validateWithException(validator, dto);
//不含税费率计算
BigDecimal expenseAmout = getAmt(dto.getExpenseAmt(), dto);
//含税梯级费率计算
BigDecimal expenseTaxAmout = getAmt(dto.getExpenseTaxAmt(), dto);
fee.setExpenseTotalAmout(expenseAmout);
fee.setExpenseTotalTaxAmout(expenseTaxAmout);
return fee;
}
使用到的工具类
package com.ruoyi.common.core.utils.bean;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
/**
* bean对象属性验证
*
* @author ruoyi
*/
public class BeanValidators
{
public static void validateWithException(Validator validator, Object object, Class<?>... groups)
throws ConstraintViolationException
{
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty())
{
throw new ConstraintViolationException(constraintViolations);
}
}
}
示例2:
Set<ConstraintViolation<BizEntryOrderDetail>> validate = validator.validate(goods);
if (!validate.isEmpty()) {
return AjaxResult.error("入库单导入失败:" + validate.iterator().next().getMessage());
}
推荐使用示例1,使用工具类,使代码更加简洁。