SpringBoot参数验证以及组验证Validation、格式验证等的使用,参数少的话好办,但参数多了,代码中就会出现大量的if-else语句.虽然使用这种方法简单直接,但也有缺点。一来会降低开发效率,因为我们需要验证的参数会存在很多地方,不同的地方会重复验证,二来会降低代码的可读性,因为业务代码中夹杂了太多多余的工作代码。所以我们可以使用验证器组件来代替我们不必要的编码操作。这篇文章是根据验证者的介绍信息,也是结合我在项目中的实际经验总结出来的,希望对大家有所帮助。1什么是validatorBeanValidation是Java定义的一套基于注解的数据验证规范。从JSR303的1.0版本升级到JSR349的1.1版本,再到JSR380的2.0版本(2.0于2017.08完成)。已经出现了三个版本。需要注意的是,JSR只是一个标准,规定了验证注解的一些规范,但并未实现,比如@Null、@NotNull、@Pattern等,位于javax.validation.constraints包下.hibernatevalidator是这个规范的实现,并添加了一些其他的验证注解,比如@NotBlank、@NotEmpty、@Length等,位于org.hibernate.validator.constraints包下。如果我们的项目使用的是SpringBoot,那么在spring-boot-starter-web中已经集成了hibernatevalidator框架,所以不需要再添加其他依赖。如果不是SpringBoot项目,需要添加如下依赖。二、注解介绍1validator内置注解hibernatevalidator扩展了以下注解的定义:3、使用起来比较简单,使用注解。具体分为单参数验证和对象参数验证。单参数校验是指controller接口根据单个参数接收前端值,不带封装对象接收。如果有封装对象,就是对象参数校验。1单参数验证单参数验证只需要在参数前加上注解即可,如下图:publicResultdeleteUser(@NotNull(message="idcannotbeempty")Longid){//dosomething}但是要付出一点注意,如果使用单参数校验,必须在controller类中添加@Validated注解,如下所示:@RestController@RequestMapping("/user")@Validated//单参数校验需要注解publicclassUserController{//dosomething}2objectParametervalidation使用对象参数校验时,需要先在对象的校验属性上添加注解,然后在Controller方法的对象参数前添加@Validated注解,如下所示:publicResultaddUser(@ValidatedUserAOuserAo){//dosomething}publicclassUserAO{@NotBlankprivateStringname;@NotNullprivateIntegerage;...}注解分组在对象参数验证的场景中,有一个特殊的场景,同一个参数对象在不同的??场景下有不同的校验规则。比如创建对象时不需要传入id字段(id字段为主键,系统生成,用户不指定),但是修改对象时必须传入id字段目的。在这种情况下,需要对注释进行分组。1)组件有一个默认组Default.class,那么我们可以再创建一个组UpdateAction.class,如下图:publicinterfaceUpdateAction{}2)在参数类中需要校验的属性上,添加groups属性到注解:publicclassUserAO{@NotNull(groups=UpdateAction.class,message="idcannotbeempty")privateLongid;@NotBlankprivateStringname;@NotNullprivateIntegerage;...}如上所示,表示id字段只在下检查UpdateAction组,默认情况下,在这种情况下,名称字段和年龄字段将被选中。然后,在controller的方法中,在@Validated注解中指定使用何种场景即可。如果不指定,则表示使用Default.class,如果使用其他组,则需要显示和指定。以下代码表示在addUser()接口中根据默认情况进行参数校验,在updateUser()接口中根据默认情况和UpdateAction分组联合校验参数。publicResultaddUser(@ValidatedUserAOuserAo){//dosomething}publicResultupdateUser(@Validated({Default.class,UpdateAction.class})UserAOuserAo){//dosomething}对象嵌套如果参数对象中嵌套有对象属性需要校验,嵌套的对象属性也需要校验,那么需要在对象属性上加上@Valid注解。publicclassUserAO{@NotNull(groups=UpdateAction.class,message="idcannotbeempty")privateLongid;@NotBlankprivateStringname;@NotNullprivateIntegerage;@ValidprivatePhonephone;……}publicclassPhone{@NotBlankprivateStringoperatorType;@NotBlankprivateStringphoneNum;}之后会抛出异常验证失败。我们只需要在全局异常处理类中捕获参数验证失败的异常,然后将错误信息添加到返回值中即可。捕获异常的方法如下,返回值Result是我们系统自定义的返回值类。@RestControllerAdvice(basePackages={"com.alibaba.dc.controller","com.alibaba.dc.service"})publicclassGlobalExceptionHandler{@ExceptionHandler(value={Throwable.class})ResulthandleException(Throwablee,HttpServletRequestrequest){//异常处理}}需要注意的是参数丢失抛出的异常是MissingServletRequestParameterException,单参数校验失败抛出的异常是ConstraintViolationException,get请求的对象参数校验失败抛出的异常是BindException,异常post请求抛出的对象参数校验失败后抛出的异常为MethodArgumentNotValidException。不同的异常对象结构不同,提取异常信息的方法也不同。如下图所示:1)MissingServletRequestParameterExceptionif(einstanceofMissingServletRequestParameterException){Resultresult=Result.buildErrorResult(ErrorCodeEnum.PARAM_ILLEGAL);Stringmsg=MessageFormat.format("缺少参数{0}",((MissingServletRequestParameterException)e).getParameterName());result.setMessage(msg);returnresult;}2)ConstraintViolationException异常if(einstanceofConstraintViolationException){//单个参校实验异常Resultresult=Result.buildErrorResult(ErrorCodeEnum.PARAM_ILLEGAL);Set
