目录
在项目中添加spring-boot-starter-validation依赖项:
关于Knife4j的常用注解:
@Api:
添加在控制器类上,通过此注解的tags属性可配置模块名称,可以在每个模块名称之前添加数字,则API文档会根据此名称(名称前面的数字)升序排列,例如:
@Api(tags = "01. 相册管理模块")
@ApiOperation:添加在处理请求的方法上,通过此注解的value属性可配置业务名称,例如:
@ApiOperation("添加相册")
@ApiOperationSupport:添加在处理请求的方法上,通过此注解的order属性可配置各业务的排序,最终将按照order属性的值(int类型)升序排列,例如:
@ApiOperationSupport(order = 100)
@ApiModelProperty:添加在POJO类型的属性上,通过此注解的value属性可配置请求参数的描述文本,通过此注解的required属性可配置是否必须提交此参数(注意:此配置并不具备检查功能),通过此注解的example属性可以配置示例值,例如:
@ApiModelProperty(value = "相册名称", required = true)
@ApiImplicitParam:添加在处理请求的方法上,通过此注解的name属性表示你需要配置方法的哪个请求参数,通过此注解的value属性配置请求参数的描述文本,通过此注解的required属性可配置是否必须提交此参数,通过此注解的dataType属性配置请求参数的数据类型,通过此注解的example属性可以配置示例值,例如:
@ApiImplicitParam(name = "id", value = "相册ID", required = true, dataType = "long")
@ApiImplicitParams:添加在处理请求的方法上,当存在多个请求参数的说明是通过@ApiImplicitParam进行配置时,应该将多个@ApiImplicitParam配置作为当前注解的参数值,例如:
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "相册ID", required = true, dataType = "long"), @ApiImplicitParam(name = "username", value = "用户名", required = true) })
去除响应结果中的null 当需要“去除响应时为null的数据”时,可以在对应的属性上添加@JsonInclude注解进行配置,当注解属性取值为NON_NULL时,表示“不为null时,JSON结果中将包含此属性”,例如:
@Data public class JsonResult implements Serializable {
private Integer state;
@JsonInclude(JsonInclude.Include.NON_NULL) // 重要
private String message;
// 暂不关心其它代码
}
也可以将注解配置在类上,则类中所有属性都会应用此注解的配置,例如:
@Data @JsonInclude(JsonInclude.Include.NON_NULL) // 重要
public class JsonResult implements Serializable {
private Integer state;
private String message;
}
如果项目中还有其它的类的对象会被控制器返回到客户端,当需要去除其它类的对象中为null的属性时,还需要在其它类上也添加相同的配置!或者,在配置文件中,通过spring.jackson.default-property-inclusion属性进行全局配置,例如:
image-20230224141853975
如果同时使用以上3种配置方式,将采取“范围越小越优先”的原则。
Spring Validation 关于Spring Validation Spring Validation是用于检查参数的基本格式有效性的框架。
在项目中添加spring-boot-starter-validation依赖项:
<!-- Spring Boot支持Spring Validation的依赖项,用于检查参数的基本有效性 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
提示:在学习时,为了更清楚的了解执行过程,建议暂时不启用全局异常处理器!
检查POJO类型的参数 在需要被检查的参数前添加@Validated或@Valid注解,表示需要检查此参数,例如:
@PostMapping("/add-new") // ↓↓↓↓↓↓ 新增注解
public JsonResult addNew(@Valid AlbumAddNewDTO albumAddNewDTO)
{
//
}
然后,在POJO类型的属性上使用“检查注解”(例如:@NotNull表示“不允许为null”)来配置检查规则,例如:
@Data
public class AlbumAddNewDTO implements Serializable {
@NotNull // 新增注解
private String name;
// 暂不关心其它代码
}
当客户端提交的请求中不包含name属性时,服务器端将响应400错误!并且,在服务器端的控制台会有以下警告信息:
2023-02-24 14:42:16.018 WARN 22020 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'albumAddNewDTO' on field 'name': rejected value [null]; codes [NotNull.albumAddNewDTO.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [albumAddNewDTO.name,name]; arguments []; default message [name]]; default message [不能为null]] 处理检查失败时的异常 当检查失败时,Spring Validation框架会抛出BindException,同时,此框架还有DefaultHandlerExceptionResolver对此异常进行处理,以至于默认的失败效果是响应400错误。
可以在全局异常处理器中添加处理BindException异常的方法:
@ExceptionHandler
public JsonResult handleBindException(BindException e) {
String message = "请求参数格式错误!!!";
return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}
在处理异常时,应该对错误的原因进行更加精准的描述,此描述文本需要通过检查注解的message属性进行配置,例如:
@Data
public class AlbumAddNewDTO implements Serializable {
@NotNull(message = "必须填写相册名称!") // 配置注解参数
private String name;
// 暂不关心其它代码
然后,在处理异常时,可以通过BindException对象的getFieldError().getDefaultMessage()获取此信息,例如:
@ExceptionHandler
public JsonResult handleBindException(BindException e) {
String message = e.getFieldError().getDefaultMessage();
return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}
但是,当同时存在多种错误时,以上处理方式只能提示多种错误中的某1种,如果需要提示全部错误,需要调整为:
@ExceptionHandler
public JsonResult handleBindException(BindException e) {
StringBuilder stringBuilder = new StringBuilder();
List<FieldError> fieldErrors = e.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
stringBuilder.append(fieldError.getDefaultMessage());
}
String message = stringBuilder.toString();
return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}
关于快速失败 快速失败表现为:当检查参数的格式不通过时,不再继续对其它参数的检查!
相关配置代码如下:
package cn.tedu.csmall.product.config;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.validation.Validation;
/**
* Validation配置类
*
* @author java@tedu.cn
* @version 0.0.1
*/
@Slf4j
@Configuration
public class ValidationConfiguration {
public ValidationConfiguration() {
log.debug("创建配置类对象:ValidationConfiguration");
}
@Bean
public javax.validation.Validator validator() {
return Validation.byProvider(HibernateValidator.class)
.configure() // 开始配置
.failFast(true) // 配置快速失败
.buildValidatorFactory() // 构建Validator工厂
.getValidator(); // 从Validator工厂中获取Validator对象
}
}
检查简单类型的参数 当需要检查简单类型的参数时,需要先在当前类上添加@Validated注解,例如:
@RestController
@RequestMapping("/album")
@Validated // 新增
public class AlbumController {
// 暂不关心
}
然后,在需要检查的参数上添加检查注解,例如:
@PostMapping("/delete")
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 检查注解的配置
public JsonResult delete(@RequestParam @Range(min = 1) Long id) {
albumService.delete(id);
return JsonResult.ok();
}
提示:以上参数上的@RequestParam只是临时使用的,如果没有此注解,在API文档的调试界面中暂时无法显示参数的输入框。
当提交的请求参数id值小于1时,会响应500错误,并且在服务器端的控制台会提示错误,例如:
javax.validation.ConstraintViolationException: delete.id: 需要在1和9223372036854775807之间 则可以在全局异常处理器中添加处理以上异常的方法:
@ExceptionHandler
public JsonResult handleConstraintViolationException(ConstraintViolationException e) {
StringBuilder stringBuilder = new StringBuilder();
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
stringBuilder.append(constraintViolation.getMessage());
}
String message = stringBuilder.toString();
return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, message);
}
常用检查注解 使用Spring Validation框架时,常用的检查注解有:
@NotNull:不允许为null值,即客户端必须提交此参数 @NotEmpty:不允许为空值,即长度为0的字符串 仅能作用于字符串类型的参数 @NotBlank:不允许为空白值,即仅由空格、TAB、换行符组成的字符串 仅能作用于字符串类型的参数 @Pattern:通过此注解的regexp属性指定正则表达式,检查参数是否匹配此正则表达式 仅能作用于字符串类型的参数 @Range:限制数值型的参数值的有效区间 仅能作用于数值型的参数 以上2个注解可以同时添加在1个参数上。
以上@Range仅当参数值存在时执行检查,如果调用此方法时,传入的参数值为null,则此注解是无效的!所以,这类注解通常与@NotNull一起使用!
在源代码中,按住Ctrl键点击检查注解所在的包!
今天的分享希望对各位有所帮助![](https://i-blog.csdnimg.cn/blog_migrate/37588641fa0c1c28dafa302a0c26d878.jpeg)