Bean Validator

一、jdk内置标签

Bean Validation 中内置的 constraint:
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

同时,还可以使用hibernate扩展的validator标签:

使用样例:

public class UserVo{//大于0.01,不包含0.01
@NotNull
@DecimalMin(value = "0.01", inclusive = false)
private Integer greaterThan;//大于等于0.01
@NotNull
@DecimalMin(value = "0.01", inclusive = true)
private BigDecimal greatOrEqualThan;@NotEmpty(message = "message不能为空")
@Length(min = 1, max = 20, message = "message不能为空")
//不能将Length错用成Range
//@Range(min = 1, max = 20, message = "message不能为空")
private String message;
}

二、集成spring boot

spring-boot-starter-web已经默认帮我们声明、集成了validation-api和hibernate-validator,所以引入spring-boot-starter-web即可。
1、pom配置:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>#如果parent为spring-boot-starter-parent,那version可以省略#<version>${latest.version}</version>
</dependency>

2、校验模式配置:

@Configuration
public class ValidatorConfiguration {@Beanpublic Validator validator(){ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ).configure()//false:普通模式(会校验完所有的属性,然后返回所有的验证失败信息)//true:快速失败返回模式(只要有一个验证失败,则返回).failFast( true ).buildValidatorFactory();Validator validator = validatorFactory.getValidator();return validator;}
}

3、定义统一异常处理:

@ControllerAdvice
public class ExceptionAspect {/*** 统一处理入参异常 MethodArgumentNotValidException* @param e* @return*/@ResponseBody@ExceptionHandler(MethodArgumentNotValidException.class)public BaseResponseVo methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {List<String> errorInformation = e.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList());return BaseResponseVo.builder().code(BaseConstant.INVALID_PARAMETER_CODE).message(errorInformation.toString()).build();}
}

4、业务校验:

@PostMapping("/something")
public void doSomething(@RequestBody @Valid UserVo uservo) {//do somethig
}

三、特殊场景

1、联级校验

当某个vo对象中又嵌套另一个vo对象时,如果想要同时校验两个vo,就需要使用联级校验,方式为在属性vo上添加@Valid即可:

@Data
public class Demo2 {@Size(min = 3,max = 5,message = "list的Size在[3,5]")private List<String> list;@NotNull@Validprivate Demo3 demo3;@Datapublic static class Demo3 {@Length(min = 5, max = 17, message = "length长度在[5,17]之间")private String extField;}
}

2、分组校验

有这样一种场景,我们定义了一个统一的requestVo,新增用户信息的时候,不需要验证userId(因为系统生成);修改的时候需要验证userId,此时就可以使用到validator的分组验证功能。如下:

  1. 定义分组场景:
/*** 插入校验分组*/
public interface InsertValidatorGroup {}/*** 列表查询校验分组*/
public interface ListValidatorGroup {}/*** 单体查询校验分组*/
public interface QueryValidatorGroup {}/*** 更新校验分组*/
public interface UpdateValidatorGroup {}/*** 删除校验分组*/
public interface DeleteValidatorGroup {}
  1. 配置requestVo的校验:
@Data
public class UserRequestVo {@NotBlank@Range(min = 1,max = Integer.MAX_VALUE,message = "必须大于0",groups = {UpdateValidatorGroup.class,DeleteValidatorGroup.class})/**用户id*/private Integer userId;@NotBlank@Length(min = 4,max = 20,message = "必须在[4,20]",groups = {QueryValidatorGroup.class,UpdateValidatorGroup.class,InsertValidatorGroup.class})/**用户名*/private String userName;@NotBlank@Range(min = 0,max = 100,message = "年龄必须在[0,100]",groups={ListValidatorGroup.class,UpdateValidatorGroup.class,InsertValidatorGroup.class})/**年龄*/private Integer age;@Range(min = 0,max = 2,message = "性别必须在[0,2]",groups = {ListValidatorGroup.class,UpdateValidatorGroup.class,InsertValidatorGroup.class})/**性别 0:未知;1:男;2:女*/private Integer sex;
}

如上UserRequestVo所示,可以根据不同场景设置不同的验证属性。

3.开启验证:
jdk自带的@Valid并不支持group配置,所以需要使用spring的@Validated标签

@RequestMapping("/query")public void query(@RequestBody @Validated({QueryValidatorGroup.class}) UserRequestVo u){}
@RequestMapping("/list")public void list(@RequestBody @Validated({ListValidatorGroup.class}) UserRequestVo u){}
@RequestMapping("/update")public void update(@RequestBody @Validated({UpdateValidatorGroup.class}) UserRequestVo u){}
@RequestMapping("/insert")public void insert(@RequestBody @Validated({UpdateValidatorGroup.class}) UserRequestVo u){}@RequestMapping("/delete")public void delete(@RequestBody @Validated({DeleteValidatorGroup.class}) UserRequestVo u){}

3、序列校验

除了按组指定是否验证之外,还可以指定组的验证顺序,前面组验证不通过的,后面组不进行验证:

  1. 配置校验顺序:
@GroupSequence({GroupA.class, GroupB.class, Default.class})
public interface GroupOrder {}
  1. 开启验证:
@RequestMapping("/groupOrder")
public void groupOrder(@Validated({GroupOrder.class}) UserRequestVo u){}

四、dubbo集成

在dubbo微服务中,已经可以直接集成validator,无需再使用工具类模式或Filter模式。
1、生产者:

  <dubbo:provider delay="-1" timeout="5000" threads="600" threadpool="fixed" loadbalance="roundrobin" accesslog="true"retries="0" validation="true"/>

2、消费者:

<dubbo:consumer check="false" timeout="60000" retries="0" validation="true"/>

3、定义统一异常处理:

@ControllerAdvice
public class DefaultExceptionHandler {@ExceptionHandler({RpcException.class})@ResponseBodypublic ResponseVo RpcException(Exception ex, Model model) {logger.error("rpc接口参数校验异常。{}", ex.getMessage());String errMsg = ((ConstraintViolationException) ex.getCause()).getConstraintViolations().iterator().next().getMessage();return ResponseVo.error(ARG_ERROR_CODE, errMsg);}
}

Bean Validator详解相关推荐

  1. java spring bean配置文件_Spring基于xml文件配置Bean过程详解

    这篇文章主要介绍了spring基于xml文件配置Bean过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 通过全类名来配置: class:be ...

  2. Java Bean Validation 详解

    前言 最近维护一个老项目,项目使用最原始的Servlet,项目中充斥着各种类似判空的简单校验,为了减少重复代码,因此需要手动引入 Java 的 Bean Validation. Java Bean V ...

  3. Springboot使用bean方式详解(附代码)

    上一章节中介绍了springboot创建bean的几种方式:注解形式(@Controller/@Service/@Component/@Repository)和@Configuration/@Bean ...

  4. Spring bean - scope详解

    ​ Scope是定义Spring如何创建bean的实例的. 在创建bean的时候可以带上scope属性,scope有下面几种类型. Singleton 这也是Spring默认的scope,表示Spri ...

  5. Spring学习(七)bean装配详解之 【通过注解装配 Bean】【自动装配的歧义解决】...

    本文借鉴:Spring学习,@Bean 的用法(特此感谢!) 自动装配 1.歧义性 我们知道用@Autowired可以对bean进行注入(按照type注入),但如果有两个相同类型的bean在IOC容器 ...

  6. Spring学习(六)bean装配详解之 【通过注解装配 Bean】【基础配置方式】

    本文借鉴:Spring学习(特此感谢!) 通过注解装配 Bean 1.前言 优势 1.可以减少 XML 的配置,当配置项多的时候,XML配置过多会导致项目臃肿难以维护 2.功能更加强大,既能实现 XM ...

  7. Spring学习(五)bean装配详解之 【XML方式配置】

    本文借鉴:Spring学习(特此感谢!) 一.配置Bean的方式及选择 配置方式 在 XML 文件中显式配置 在 Java 的接口和类中实现配置 隐式 Bean 的发现机制和自动装配原则 方式选择的原 ...

  8. @Configuration和@Bean注解详解

    本文来详细说下@Configuration和@Bean注解 文章目录 @Configuration注解 @Bean注解 @Configuration注解 @Configuration注解源码 pack ...

  9. 被各种注解搞晕了?那快来看看Spring Bean注解详解!

    前言 本篇博客中,我们将会讨论用于声明不同类型 Beans 的几种最常用的 Spring Bean 注解. 众所周知,Spring 容器中有许多配置 Bean 的方法,我们既可以通过 XML 配置,也 ...

最新文章

  1. mysql模糊查询的优化方法--亲自实践
  2. ros的密码忘记解决方法
  3. 2.9 情感分类-深度学习第五课《序列模型》-Stanford吴恩达教授
  4. 网络测试及故障诊断方法及工具
  5. 【Linux网络编程】因特网的IP协议是不可靠无连接的,那为什么当初不直接把它设计为可靠的?
  6. jfinal连接mysql数据库_JFinal中怎么获得当前数据库连接的数据库类型?
  7. java 异常机制_深入理解Java异常处理机制
  8. 计算机的软件及功能是什么意思,M1版MacBook能兼容啥软件?超详细的兼容测试
  9. 计算机平均分函数a,平均值计算函数Average、Averagea、AverageIfs、Trimmean
  10. 【友情链接】吊打我的巨佬们
  11. 在抖音找罗永浩干掉辣条
  12. 计算机打字正确姿势,电脑打字手指的正确姿势,涨知识了
  13. 计算机等级考试四级网络工程师真题,计算机四级网络工程师试题及答案
  14. 网站建设的基本步骤有哪些
  15. Build On实验学习心得
  16. 最新最全 Android 常用开源库总结
  17. C#界面设计--4--C#实现多个IP摄像头画面预览以及截图
  18. Unity 视频播放杂谈
  19. android案例之图片播放器
  20. python爬取历史天气查询_Python爬虫实战-爬取历史天气数据

热门文章

  1. 从项目采购管理人员角度,浅谈工程总承包项目采购风险管理
  2. (ASP) 数据库打开方式
  3. C++ 模板总结,很全面!
  4. C51-串口与74LS164芯片实现倒计数
  5. 变量(自动变量、静态变量、寄存器变量、外部变量)与C的内存分配malloc/free、calloc/recalloc
  6. Ising模型的2D模拟
  7. Tinyxml简单使用法
  8. mysql-5.0.83删除_【实验】WindowsXP + MySQL5 + Apache2 + PHP5 + phpMyAdmin环境搭建
  9. 阅读理解机器问答系统
  10. 【愚公系列】2023年05月 攻防世界-Web(inget)