背景
首先不使用Hibernate-Validator的时候,我们要想校验参数的正确性,需要在Controller里指定
User:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private String email;
private String password;
private Integer age;
}
HelloController:
@RestController
@RequestMapping("/user")
public class HelloController {
@RequestMapping("/add")
public String add(@RequestBody User user){
// 参数检查
if (user.getName() == null || user.getEmail() == null){
return "error";
}
return "success";
}
}
- 验证代码繁琐,重复劳动
- 方法内代码显得冗长
检验步骤
引入依赖
我们可以使用Hibernate-Validator来简化这些操作,Hibernate Validator是Hibernate提供的一个开源框架,并不是只能在使用Hibernate 的时候来使用
如果使用的是SpringBoot,不需要再引Hibernate-Validator 依赖,因为spring-boot-starter-web包中已经包含了Hibernate-Validator 依赖,如果不是Springboot,可能就要添加对应依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
注解标识
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@NotBlank(message = "姓名不能为空")
private String name;
@NotBlank
@Email
private String email;
@Min(value = 1, message = "年龄不能小于1")
@Max(value = 100, message = "年龄不能大于100")
private Integer age;
}
controller类添加校验注解
@RestController
@RequestMapping("/user")
public class HelloController {
@RequestMapping("/add")
public String add(@RequestBody @Valid User user){
System.out.println(user);
return "success";
}
}
如果是单个参数在Controller校验,需要在类上标明@Valid,并且在接收参数上标明校验规则
@RestController
@RequestMapping("/user")
@Valid
public class HelloController {
@RequestMapping("/add")
public String add(@NotBlank(message = "姓名不能为空") @RequestParam("name") String name){
System.out.println(name);
return "success";
}
}
返回的错误信息:
{
"timestamp": "2019-12-21T05:30:38.341+0000",
"status": 400,
"error": "Bad Request",
"message": "Required String parameter 'name' is not present",
"path": "/test1/user/add"
}
返回结果自定义
如果对默认返回的错误信息不满意,可以使用Spring的@ControllerAdvice来进行异常的捕获。
为了使用方便,我创建了一个序列化的类,用于消息的返回
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@Data
public class ServerResponse<T> implements Serializable {
private static final long serialVersionUID = 1L;
private int code; //状态
private String msg; //信息
private T data; //数据
private ServerResponse(int code) {
this(code,null,null);
}
private ServerResponse(int code,T data){
this(code,null,data);
}
private ServerResponse(int code,String msg){
this(code,msg,null);
}
private ServerResponse(int code,String msg,T data){
this.code = code;
this.msg = msg;
this.data = data;
}
public static <T> ServerResponse<T> createByErrorCodeMessage(int errorCode,String errorMessage){
return new ServerResponse<T>(errorCode,errorMessage);
}
}
添加ControllerAdvice:
@ControllerAdvice
@ResponseBody
public class CustomAdvice {
private final static Logger logger = LoggerFactory.getLogger(CustomAdvice.class);
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(MissingServletRequestParameterException.class)
public ServerResponse<String> handleHttpRequestMethodNotSupportedException(Exception e) {
logger.error("不支持当前请求方法", e);
return ServerResponse.createByErrorCodeMessage(HttpStatus.METHOD_NOT_ALLOWED.value(),HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
}
}
此时返回结果就是
{
"code": 405,
"msg": "Method Not Allowed",
}
校验注解:

5.png
Tip:三种判断为空的区别
@NotNull:主要用在基本数据类型上(Int,Integer,Double)
举例:
@NotNull(message = “年龄不能为空”)
private Integer age;
@NotBlank:主要用在String字符串上面(String)
举例:
@NotBlank(message = “名字不能为空”)
private String name;
@NotEmpty; 加了@NotEmpty注解的String类 ,Collection集合,Map ,数组,这些是不能为null或者长度为0的;(String ,Collection,Map的isEmpty()方法)