在SpringMVC中,我们通常会对入参进行各种校验,如果每个接口都写一遍校验,这样会显得特别麻烦。 这里我们通过在入参的属性中加入注解的方式来实现自动校验。 首先Maven引入下面三个包,版本根据实际情况修改。 ```xml <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.3.Final</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.1.1.GA</version> </dependency> ``` 我们在实体属性中加入注解`@NotBlank` ```java public class User{ private String id; @NotBlank(message = "账号或密码不能为空") private String userName; @NotBlank(message = "账号或密码不能为空") private String password; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } ``` 在Controller的入参前加上`@Valid` ```java @RequestMapping(name = "登录", value = "/login") public Object login (@Valid User user) throws MyException { WebApiResult<?> result = new WebApiResult<>(); return result; } ``` 这样写如果出现参数为空的情况,会抛出`org.springframework.validation.BindException`这个异常 我们可以在参数后面加上`BindingResult errorResult`来获取这个异常 ```java @RequestMapping(name = "登录", value = "/login") public Object login (@Valid User user, BindingResult errorResult) throws MyException { WebApiResult<?> result = new WebApiResult<>(); if(errorResult.hasErrors()){ for (FieldError fieldError : e.getBindingResult().getFieldErrors()) { logger.error(fieldError.getDefaultMessage()); } result.setCode(ResultCode.PARAME_ERROR.getCode()); result.setMsg(errorResult.getBindingResult().getFieldErrors().get(0).getDefaultMessage()); return result; } return result; } ``` 但我们可以用一种更优雅的方式,去处理这种通用的异常,我们可以使用`@ControllerAdvice`这个注解定义一个类,拦截异常并统一处理 ```java @ControllerAdvice public class DefaultExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(DefaultExceptionHandler.class); @ExceptionHandler({ BindException.class }) @ResponseBody public WebApiResult<?> processBindException(BindException e) { for (FieldError fieldError : e.getBindingResult().getFieldErrors()) { logger.error(fieldError.getDefaultMessage()); } WebApiResult<?> result = new WebApiResult<>(); result.setCode(ResultCode.PARAME_ERROR.getCode()); result.setMsg(e.getBindingResult().getFieldErrors().get(0).getDefaultMessage()); return result; } } ``` 这样我们就不用在每个入参的后面都加上`BindingResult errorResult`来获取异常了。 附上其它校验数据的注解: | 限制 | 说明 | | ------------ | ------------ | |@Null|限制只能为null| |@NotNull |限制必须不为null| |@AssertFalse| 限制必须为false| |@AssertTrue |限制必须为true| |@DecimalMax(value) |限制必须为一个不大于指定值的数字| |@DecimalMin(value) |限制必须为一个不小于指定值的数字| |@Digits(integer,fraction)| 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction| |@Future| 限制必须是一个将来的日期| |@Max(value)| 限制必须为一个不大于指定值的数字| |@Min(value)| 限制必须为一个不小于指定值的数字| |@Past| 限制必须是一个过去的日期| |@Pattern(value)| 限制必须符合指定的正则表达式| |@Size(max,min)| 限制字符长度必须在min到max之间| |@Past |验证注解的元素值(日期类型)比当前时间早| |@NotEmpty |验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)| |@NotBlank |验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格| |@Email |验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式|