![ca1f839f264c7335ffae58b8fd86aaaf.png](https://i-blog.csdnimg.cn/blog_migrate/73ae3474e690a3861abd1799e026e1bf.jpeg)
背景
在常见的b/s架构中,对于前端输入的参数我们需要做相应的校验,相信这种代码在后端非常常见:
@RestController
public class UserController {
public UserResponse check(@RequestBody UserRequest req) throws Exception {
if (StringUtils.isEmpty(req.getUserId())) {
throw new IllegalArgumentException("'userId' can't be null !");
}
if (StringUtils.isEmpty(req.getName())) {
throw new IllegalArgumentException("'Name' can't be null !");
}
...
}
这种硬编码的方式虽然能实现业务功能,但是却非常繁琐,试想一下,如果前端传入的参数几十个,这种校验是非常没有技术含量而且还特别容易遗漏。
SpringBoot vaild
Spring3支持JSR-303验证框架,JSR-303 是Java EE 6 中的一项子规范,叫做BeanValidation,官方参考实现是hibernate Validator(与Hibernate ORM 没有关系),JSR 303 用于对Java Bean 中的字段的值进行验证。
spring-boot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。比如,我们判断一个输入参数是否合法,可以用如下方式
一 基础使用
因为spring-boot已经引入了基础包,所以直接使用就可以了
1 首先在controller上声明需要对数据进行校验
@RequestMapping(value="/url.json",method= {RequestMethod.POST})
@ResponseBody
@Transactional
public Result> xxmethod( @RequestBody @Validated XoPO xoPo)
throws ParseException, UnsupportedEncodingException {}
2 然后在bean上声明需要被校验的字段
public class XoPO{
@validated
private List personList;@NotNull@Size(max=32,message="code is null")private String code;@NotBlank@Size(max=32,message="product is null")private String product;
}
而后,当输入不能满足条件是,就会抛出异常,而后统一由异常中心处理也可以用BindingResult,但是用了这个后就必须手动处理异常,侵入了正常的逻辑过程,并不推荐
二 常用注解类型
注意,不要错用了异常类型,比如在int上不可用@size
常用注解如下
限制 说明
@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格式
三 嵌套校验
如果一个类中包含了另外一个实体类,那么在上面加上@Validated即可,比如上面的
public class XoPO {
@validated
private List personList;
}
四 @pathvariable的校验
spring-boot可能目前并不支持对参数的验证
public Result> xoById( @NotNull @NotBlank @Size(min=10,max=32)@PathVariable(value="accountId") String id) {}
但目前还无法抛出异常, 可能在spring的下一个版本中解决,或者不用@Pathvariable,而在service中
Class XoService{
public xoMethon( @NotNull String id){
}
}
五 @RestControllerAdvice统一处理类
@RestControllerAdvice
public class UserHandlerAdvice {
private Map<String, Object> getValid(BindingResult bindingResult) {
Map<String, Object> data = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
data.put(error.getField(), error.getDefaultMessage());
}
return data;
}
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Map<String, Object> exception(HttpServletResponse response, MethodArgumentNotValidException exception,
HandlerMethod handler) throws IOException {
log.warn("system error:", exception);
return this.getValid(exception.getBindingResult());
}
}
![263d886da18b019d3ab93b4ca98e092e.png](https://i-blog.csdnimg.cn/blog_migrate/7dce087e87b5d03141d4315960b5219b.png)
本公众号团队成员由饿了么、阿里、蚂蚁金服等同事组成,关注架构师之巅,可以了解最前沿的技术。
·END·
架构师之巅时刻关注最前沿的技术
jiagoushizhidian