告别if-else炼狱!Spring Boot参数校验终极指南,代码精简70%
创建名为的工具类,定义校验方法/*** 商品实体类* @author 蜡笔小鑫星*/Validation.byProvider(HibernateValidator.class):使用HibernateValidator作为验证提供者,用于验证Java Bean的约束configure:用于对ValidatorFactory进行配置,可以设置不同的参数来调整验证行为failFast:配置是否快速失
种一棵树最好的时间是10年前,其次就是现在,加油!
--by蜡笔小柯南
你是否还在Controller里写满if(userName == null)这样的判空代码?每次新增参数都要复制粘贴一堆校验逻辑?不仅繁琐,而且极易出错!本文将带你使用Spring Validation一站式解决参数校验难题,用注解代替繁琐逻辑,让代码更简洁、更健壮!
依赖导入
在pom文件中导入validation
的依赖,添加依赖坐标
<!-- validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.2.2</version>
</dependency>
自定义参数校验工具类
创建名为BeanValidator
的工具类,定义validateObject
校验方法
/**
* 商品实体类
*
* @author 蜡笔小鑫星
*/
public class BeanValidator {
private static Validator validator = Validation.byProvider(HibernateValidator.class).configure().failFast(true)
.buildValidatorFactory().getValidator();
public static void validateObject(Object object, Class<?>... groups) {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (constraintViolations.stream().findFirst().isPresent()) {
throw new ValidationException(constraintViolations.stream().findFirst().get().getMessage());
}
}
}
-
Validation.byProvider(HibernateValidator.class):使用HibernateValidator作为验证提供者,用于验证Java Bean的约束
-
configure:用于对ValidatorFactory进行配置,可以设置不同的参数来调整验证行为
-
failFast:配置是否快速失败,可配置为true或fasle
- true:配置为true,则在验证参数的过程中,碰到第一个不满足约束的就立即停止,不再向后继续验证
- false:配置为false,则会收集所有不满足约束的错误信息,而不是在第一个约束不满足时就停止
-
buildValidatorFactory().getValidator():构建ValidatorFactory实例,获取Validator对象,Validator是执行验证操作的核心接口
在validateObject
方法中,调用validator.validate(object, groups)
去校验参数,返回一个Set集合。如果有参数校验没有通过,那么Set集合中保存的就是未通过校验的参数数据;如果参数校验全部通过,那么Set集合中的元素个数就是0。
数据校验
在类的字段上,添加对应的注解,以及校验不通过时的错误信息
/**
* 商品实体类
*
* @author 蜡笔小鑫星
*/
public class Goods {
@NotBlank(message = "商品名称不能为空")
private String goodsName;
@NotNull(message = "商品数量不能为空")
private Integer goodsCount;
@NotNull(message = "商品价格不能为空")
@DecimalMin(value = "0.0", inclusive = false, message = "商品价格必须大于0")
private BigDecimal price;
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public Integer getGoodsCount() {
return goodsCount;
}
public void setGoodsCount(Integer goodsCount) {
this.goodsCount = goodsCount;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
调用BeanValidator.validateObject()方法,完成参数校验
/**
* 单元测试类
*
* @author 蜡笔小鑫星
*/
@SpringBootTest
class ApplicationTests {
@Test
public void testValidator() {
Goods goods = new Goods();
goods.setGoodsName("商品1");
goods.setGoodsCount(10);
try {
BeanValidator.validateObject(goods);
} catch (ValidationException e) {
System.out.println(e.getMessage());
}
}
}
try-catch中捕获了 ValidationException
异常,打印了异常的message信息。
这里我们以商品价格为例,设置了商品名称、商品数量,没有设置商品价格属性,所以验证完成后输出:商品价格不能为空。
两种校验方式的对比
普通if方式
构建Controller
,使用if
的方式进行入参校验
/**
* @author 蜡笔小鑫星
*/
@RestController
@RequestMapping("/goods")
public class GoodsController {
@PostMapping("/validate")
public void goods(@RequestBody Goods goods) {
String goodsName = goods.getGoodsName();
if (goodsName == null) {
System.out.println("商品名称不能为空");
return;
}
Integer goodsCount = goods.getGoodsCount();
if (goodsCount == null) {
System.out.println("商品数量不能为空");
return;
}
BigDecimal price = goods.getPrice();
if (price == null) {
System.out.println("商品价格不能为空");
return;
}
BigDecimal zero = new BigDecimal("0.0");
if (price.compareTo(zero) <= 0) {
System.out.println("商品价格必须大于0");
return;
}
System.out.println("模拟其他业务逻辑处理...");
}
}
可见,非常多的if
代码,这还只是校验3个参数的情况下,如果需要校验的参数更多,那么会有更多的if
块,代码也会越来越臃肿。
当入参不满足条件时,控制台打印错误信息。
如:入参为以下数据
{
"goodsName": "玫瑰花",
"goodsCount": 1,
"price": "-2"
}
则输出:商品价格必须大于0
校验工具类方式
改造Controller
层代码,使用BeanValidator
工具类的方式
/**
* @author 蜡笔小鑫星
*/
@RestController
@RequestMapping("/goods")
public class GoodsController {
@PostMapping("/validate")
public void goods(@RequestBody Goods goods) {
try {
BeanValidator.validateObject(goods);
}catch (ValidationException e) {
System.out.println(e.getMessage());
return;
}
System.out.println("模拟其他业务逻辑处理...");
}
}
我们捕获了异常,把异常信息进行了打印。
使用以下数据进行验证:
{
"goodsName": "",
"goodsCount": 1,
"price": "3"
}
控制台打印输出:商品名称不能为空
可以看到,使用工具类的方式,大大减少了if
代码,只需调用BeanValidator.validateObject(goods)
就能搞定,如果后续需要新增校验其他字段,只需在Goods
类中需要校验的字段上,添加对应的注解即可。
结语
只要再涉及到参数校验,再也不用写一堆if去判断,只需要在需要校验的属性上添加注解,调用工具类方法校验即可。
现在,你已经掌握了用Spring Validation取代繁琐if-else的精髓。想象一下,当你的代码中不再充斥着重复的判空逻辑,这种清爽感是多么令人愉悦!
如果你有任何疑问或经验分享,可以在评论区留言哦~~
不管在任何时候,我希望你永远不要害怕挑战,不要畏惧失败。每一个错误都是向成功迈出的一步,每一个挑战都是成长的机会,因为每一次的努力,都会使我们离梦想更近一点。只要你行动起来,任何时候都不算晚。最后,把座右铭送给大家:种一棵树最好的时间是10年前,其次就是现在,加油!共勉 💪。
更多推荐
所有评论(0)