目录
[1 前言](#1 前言)
[2 实体参数校验的常用注解及使用方法](#2 实体参数校验的常用注解及使用方法)
[2.1 常用注解](#2.1 常用注解)
[2.2 使用方法](#2.2 使用方法)
[2.2.1 在pom.xml中引入相关依赖](#2.2.1 在pom.xml中引入相关依赖)
[2.2.2 在实体类上添加需要注解](#2.2.2 在实体类上添加需要注解)
[2.2.3 在controller类的相关方法中添加@Validated](#2.2.3 在controller类的相关方法中添加@Validated)
[2.2.4 编写异常处理器](#2.2.4 编写异常处理器)
[3 利用分组校验解决相关bug](#3 利用分组校验解决相关bug)
[3.1 bug的发现](#3.1 bug的发现)
[3.2 解决bug](#3.2 解决bug)
[3.2.1 定义分组](#3.2.1 定义分组)
[3.2.2 为注解分配分组](#3.2.2 为注解分配分组)
[3.2.3 为controller类的方法分配分组](#3.2.3 为controller类的方法分配分组)
[4 利用Default进行优化](#4 利用Default进行优化)
[4.1 对实体类的优化](#4.1 对实体类的优化)
[4.2 controller类的方法的优化](#4.2 controller类的方法的优化)
1 前言
在开发的过程中,我们常常需要对传送过来的参数进行校验,其中就有实体参数校验如下:
java
public class UserController {
//其它代码...
//这里我们需要对user中的数据进行校验
public Result update(@RequestBody User user) {
//其它...
}
}
在进行实体参数校验的时候,使用注解能极大的简化我们的代码并提升开发速度,接下来我会介绍几种常用的注解及其展示其使用方法,并对相关bug进行解决和优化。
2 实体参数校验的常用注解及使用方法
2.1 常用注解
注解 | 作用 |
---|---|
@NotNull | 值不能为Null |
@NotEmpty | 值不能为Null,且内容不能为空 |
满足邮箱格式 | |
@URL | 满足链接格式 |
@Pattern(regexp = "^\\S{x,y}$") | 字符串不能为空,且长度范围为[x,y] |
2.2 使用方法
2.2.1 在pom.xml中引入相关依赖
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.2.2 在实体类上添加需要注解
java
public class User {
@NotNull
private Integer id;//主键ID
@NotEmpty
@Pattern(regexp = "^\\S{1,10}$")
private String nickname;//昵称
@NotEmpty
@Email
private String email;//邮箱
@URL
private String userPic;//用户头像地址
//其它...
}
2.2.3 在controller类的相关方法中添加@Validated
java
public class UserController {
//其它代码...
public Result update(@RequestBody @Validated User user) {
//其它...
}
}
2.2.4 编写异常处理器
此时如果直接使用,如果前端传送的数据不符合要求,那么就会直接返回一个状态码为500的报错,然而这并不是我们想要的,因此我们必须编写一个异常处理器。在我的这篇文章《浅析SpringBoot的API参数校验》中,除了有异常处理器的编写,另外还有这些常用注解的其它食用方法。请移步。
3 利用分组校验解决相关bug
3.1 bug的发现
完成上述步骤后,我们在使用的时候可能会发现一些bug,如下
这是我们的实体类
java
public class Category {
@NotNull
private Integer id;//主键ID
@NotEmpty
private String categoryName;//分类名称
@NotEmpty
private String categoryAlias;//分类别名
//其它...
}
这是我们的controller类
java
public class CategoryController {
//其它代码...
//传入的json格式的数据只有categoryName和categoryAlias
@PostMapping
public Result add(@RequestBody @Validated Category category) {
//其它...
}
//传入的json格式的数据除了categoryName和categoryAlias,还有id
@PutMapping
public Result update(@RequestBody @Validated Category category) {
//其它..
}
}
这时候如果我们使用add方法所对应的API接口时就会失败,因为我们的id设置了@NotNull,而add方法传送过来的参数却没有id。
3.2 解决bug
如果我们能对每个注解进行分组,不同方法对应不同分组,那么问题将迎刃而解,具体操作如下:
3.2.1 定义分组
java
public class Category {
@NotNull
private Integer id;//主键ID
@NotEmpty
private String categoryName;//分类名称
@NotEmpty
private String categoryAlias;//分类别名
public interface Add{}
public interface Update{}
}
3.2.2 为注解分配分组
java
public class Category {
@NotNull(groups = Update.class)
private Integer id;//主键ID
@NotEmpty(groups = {Update.class,Add.class})
private String categoryName;//分类名称
@NotEmpty(groups = {Update.class,Add.class})
private String categoryAlias;//分类别名
public interface Add{}
public interface Update{}
}
3.2.3 为controller类的方法分配分组
java
public class CategoryController {
//其它代码...
//传入的json格式的数据只有categoryName和categoryAlias
@PostMapping
public Result add(@RequestBody @Validated(Category.Add.class) Category category) {
//其它...
}
//传入的json格式的数据除了categoryName和categoryAlias,还有id
@PutMapping
public Result update(@RequestBody @Validated(Category.Update.class) Category category) {
//其它..
}
}
这样bug就被解决了,不过如何更优雅的解决问题,还得进行优化
4 利用Default进行优化
如果我们不对实体类中的注解进行分组,那么它们就属于默认分组Default,我们可以利用这一点和继承的方式对分组校验进行优化。
4.1 对实体类的优化
java
public class Category {
@NotNull(groups = Update.class)
private Integer id;//主键ID
@NotEmpty//默认分组
private String categoryName;//分类名称
@NotEmpty//默认分组
private String categoryAlias;//分类别名
//public interface Add{}
//这里直接由Default代替了
public interface Update extends Default{}
}
4.2 controller类的方法的优化
java
public class CategoryController {
//其它代码...
//传入的json格式的数据只有categoryName和categoryAlias
//默认即Default
@PostMapping
public Result add(@RequestBody @Validated Category category) {
//其它...
}
//传入的json格式的数据除了categoryName和categoryAlias,还有id
@PutMapping
public Result update(@RequestBody @Validated(Category.Update.class) Category category) {
//其它..
}
}
对比优化前,是不是更加优雅和简洁了。