xmlstreamexception 参数实体未进行声明_如何优雅的使用SpringBoot 进行验证

ca1f839f264c7335ffae58b8fd86aaaf.png

背景

在常见的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

本公众号团队成员由饿了么、阿里、蚂蚁金服等同事组成,关注架构师之巅,可以了解最前沿的技术。

·END·

架构师之巅

时刻关注最前沿的技术

87e063dfe2b1329d66e34ae32412ed82.png

微信号:

jiagoushizhidian

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值