本文主要是介绍使用 @Validated 和 全局异常进行参数校验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
如果你用的 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的时候:
这篇关于使用 @Validated 和 全局异常进行参数校验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!