在开发Web应用程序时,数据校验是一项重要的任务,以确保用户输入的数据符合预期的格式和规则。
Spring框架提供了一套强大的校验工具,可以帮助开发者轻松地实施复杂的业务逻辑校验。
这一节将介绍如何利用Spring框架中的分组校验功能来优化校验逻辑。
分组校验的背景
商品管理系统,其中包含对品牌的管理操作,如创建新品牌或更新现有品牌的信息。
在这些不同的操作中,需要校验的字段可能会有所不同。
例如,在创建新品牌时,品牌ID应该是自动生成的,因此不应该被指定;而在更新品牌信息时,则需要指定品牌ID以确定要更新的对象。
此外,品牌名称无论是在创建还是更新时都不允许为空。
要实现这个需求,可以用JSR303的分组校验。
实现步骤
第一步:定义分组接口
为了实现这样的逻辑,我们首先需要定义分组接口。这些接口不会定义任何变量和方法,仅仅作为一个标识,用于区分不同的校验场景。
public interface AndGroup {}
public interface UpdateGroup {}
这里定义了两个分组接口,AndGroup
用于新增品牌时的校验,UpdateGroup
用于更新品牌时的校验。
因为会被其他模块共用,所以这两个接口定义在common模块中。
第二步:给校验注解指定分组
接下来,我们需要在实体类的字段上添加校验注解,并指定它们所属的分组。
@NotNull(groups = UpdateGroup.class, message = "修改必须指定品牌ID")
@Null(groups = AndGroup.class, message = "新增不能指定ID")
private Integer brandId;
@NotNull(groups = UpdateGroup.class)
保证在更新操作时brandId字段必须存在。
@Null(groups = AndGroup.class)
保证在新增操作时brandId字段必须为空。
@NotEmpty(message = "品牌名称不能为空", groups = {AndGroup.class, UpdateGroup.class})
private String brandName;
在AndGroup分组(即新增操作)和UpdateGroup分组(即更新操作)中都会生效。也就是说,在新增或更新品牌时,如果brandName字段为空或仅包含空白字符,那么校验将失败,并返回错误消息“品牌名称不能为空”。
@NotBlank(groups = AndGroup.class)
@URL(groups = UpdateGroup.class)
private String logo;
logo
在新增时必须不为空,而在更新时则必须是一个有效的URL地址,但如果不提交则不进行校验。
第三步:在Controller中使用 @Validated
最后,我们需要在Controller中使用Spring提供的 @Validated
注解来指定校验分组。
如,给BrandController
的save
接口指定校验分组为AddGroup.class
。
给BrandController
的update
接口指定校验分组为UpdateGroup.class
。
@RequestMapping("/save")
public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand){
brandService.save(brand);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
brandService.updateById(brand);
return R.ok();
}
这里,save
方法使用了 AddGroup
分组,而 update
方法使用了 UpdateGroup
分组。
这里需要注意的是,一旦我们给Controller的接口指定了分组,则实体类中的未指定分组的注解不会生效。这一点比较坑。
如下图,save
方法指定 AddGroup
分组,但是实体的属性brandId
没有指定任何分组。
调用save
接口,传了brandId
也不会报错,说明校验未生效。
测试结果
- 新增品牌:
- 如果提交了品牌ID,会提示校验失败,因为新增时品牌ID不允许指定。
- 如果未提交品牌ID,但提交的logo不是一个合法的URL地址,也会提示校验失败。
- 如果未提交logo,则不会触发URL校验。
- 更新品牌:
- 如果没有提交品牌ID,会提示校验失败,因为更新时品牌ID必须指定。
- 如果提交了非法的URL作为logo,会提示校验失败。
- 如果未提交logo,则不会触发URL校验。
结论
通过上述步骤,我们可以有效地实现根据不同业务场景的复杂校验逻辑。Spring框架中的分组校验功能使得我们可以灵活地控制哪些字段在哪些场景下需要校验,从而提高了代码的可读性和可维护性。
问题记录
过程中遇到的问题记录:谷粒商城实战踩坑笔记-JSR303