如果你用的 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>
常用的校验注解:
定义参数验证结果类:
public class RCode{
private int code;
private String msg;
public RCode(int code, String msg) {
super();
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
定义全局异常类:
需要确保下面的类能被spring扫描到,否则可能出现校验失效的情况
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = ConstraintViolationException.class)
public RCode handle1(ConstraintViolationException ex) {
StringBuilder msg = new StringBuilder();
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
String paramName = pathImpl.getLeafNode().getName();
String message = constraintViolation.getMessage();
msg.append("[").append(message).append("]");
}
return new RCode(1, msg.toString());
}
@ExceptionHandler(value = Exception.class)
public RCode handle1(Exception ex) {
ex.printStackTrace();
return new RCode(404, ex.getMessage());
}
@ExceptionHandler(ArithmeticException.class)
public RCode handle2(Exception ex) {
return new RCode(404, "算数异常");
}
@ExceptionHandler(BindException.class)
public RCode exceptionHandler(BindException e, HttpServletRequest request) {
String failMsg = e.getBindingResult().getFieldError().getDefaultMessage();
return new RCode(404, failMsg);
}
}
定义参数验证类:在需要验证的参数上面添加对应的验证注解
public class User {
public interface Default {
}
public interface Group1 {
}
@NotNull(message = "userId不能为空", groups = { Default.class, Group1.class })
private String userId;
@NotNull(message = "userName不能为空", groups = Group1.class)
private String userName;
@Range(min = 18, max = 60, message = "年龄必须在18-60之间", groups = Group1.class)
private int age;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
上面的 group 可以按照不同的group名称对参数进行不同要求的校验
controller类:
@Validated
@RestController
@RequestMapping("/testService")
public class TestController {
@ResponseBody
@RequestMapping(value = "/test", produces = "application/json;charset=utf-8", method = { RequestMethod.POST, RequestMethod.GET })
public String test(@Validated(value = { User.Default.class }) User user) {
return "userId " + user.getUserId();
}
@ResponseBody
@RequestMapping(value = "/test2", produces = "application/json;charset=utf-8", method = { RequestMethod.POST, RequestMethod.GET })
public String test2(@Validated(value = { User.Group1.class }) User user) {
return "userId " + user.getUserId();
}
@ResponseBody
@RequestMapping(value = "/test3", produces = "application/json;charset=utf-8", method = { RequestMethod.POST, RequestMethod.GET })
public String test3(@Validated(value = { User.Group1.class }) User user) {
System.out.println(1 / 0);
return "userId " + user.getUserId();
}
}
在需要校验的参数前面添加 @Validated 注解即可,针对不同接口需要不同参数,只需要在 @Validated 里面知道group的值即可
测试
test不传参数的时候:
test2只传一个userId的时候: