SpringBoot各种参数效验
原文章地址https://mp.weixin.qq.com/s/63_AKBz780xMf2YVyLAv5g
01 简单使用
引入依赖
requestBody参数校验
requestParam/PathVariable参数校验
统一异常处理
引入依赖
引入依赖
如果spring-boot版本小于2.3.x,spring-boot-starter-web会自动传入hibernate-validator依赖。如果spring-boot版本大于2.3.x,则需要手动引入依赖:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.1.Final</version>
</dependency>
对于web服务来说,为防止非法参数对业务造成影响,在Controller层一定要做参数校验的!大部分情况下,请求参数分为如下两种形式:
POST、PUT请求,使用requestBody传递参数;
GET请求,使用requestParam/PathVariable传递参数。
requestBody参数校验
POST、PUT请求一般会使用requestBody传递参数,这种情况下,后端使用DTO对象进行接收。只要给DTO对象加上@Validated或@Valid注解就能实现自动参数校验
DTO表示数据传输对象(Data Transfer Object),用于服务器和客户端之间交互传输使用的。在spring-web项目中可以表示用于接收请求参数的Bean对象。
在DTO字段上声明约束注解
@Data
public class ParamDto {
@NotBlank(message = "姓名不能为空")
private String name;
@NotNull(message = "年龄不能为空")
private Integer age;
@NotBlank(message = "信息不能为空")
private String message;
}
注意事项:
对于dto,@Validated或@Valid注解必须加在形参上,加在类上不生效get的请求参数也能用dto接收,但不能用@RequestBody,否则会报错:org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing
requestParam/PathVariable参数校验
GET请求一般会使用requestParam/PathVariable传参。如果参数比较多(比如超过6个),还是推荐使用DTO对象接收。
如果在入参上声明约束注解(如@Min等)@Length等则必须在controller类上声明注解@Validated
如果校验失败,会抛出ConstraintViolationException异常。
统一异常处理
前面说过,如果校验失败,会抛出MethodArgumentNotValidException或者ConstraintViolationException异常。在实际项目开发中,通常会用统一异常处理来返回一个更友好的提示。
比如我们系统要求无论发送什么异常,http的状态码必须返回200,由
业务码
去区分系统的异常情况。
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 效验参数异常捕获器
* @param e
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public String methodArgumentNotValidException(MethodArgumentNotValidException e){
BindingResult bindingResult = e.getBindingResult();
StringBuilder sb = new StringBuilder("校验失败:");
for (FieldError fieldError : bindingResult.getFieldErrors()) {
sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", ");
}
String msg=null;
if (sb.lastIndexOf(",")+2==sb.length()) {
msg=sb.substring(0,sb.lastIndexOf(","));
}else{
msg = sb.toString();
}
return msg;
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Result handleConstraintViolationException(ConstraintViolationException ex) {
return Result.fail(BusinessCode.参数校验失败, ex.getMessage());
}
}
注解
@ResponseStatus(HttpStatus.OK),返回正常的状态码200
@NotNull,@NotBlank,@NotEmpty的区别
@NotNull 验证任何类型的字段不为null
@NotBlank 验证字符串不为null且长度大于1
@NotEmpty 验证集合不为null,且长度大于1
其他注解
@Min,@Max 验证一个
数字类型
最小和最大,@Length(min=1,max=11,message="错误提示") 验证
字符串
类型的长度