[数据校验/数据质量] 数据校验框架:hibernate-validation
0 前言
- 其一,项目中普遍遇到了此问题,故近两天深入地研究了一下。
- 其二,能够自信地说,仔细看完本篇,就无需再看其他的Java数据校验框架的文章了。
1 数据校验框架概述
1.0 数据校验框架的产生背景
以Web项目为例,用户需要填写表单信息保存提交。
页面输入信息需要进行数据格式校验,并且返回对应的错误提示,以此来达到数据校验的目的,从而避免无效数据被保存或者提交。
这些检查工作包括必填项检查、数值检查、长度检查、身份证号码、手机号码检查等工作。
当请求参数格式不正确的时候,需要程序监测到,对于前后端分离开发过程中,数据校验还需要返回对应的状态码和错误提示信息。
如果将这些字段校验和业务逻辑混合一起写,则会:
- 代码极其臃肿,且不容易维护;
- 干扰原有逻辑;
接下来将细述在服务器端,如何对API的数据校验处理技术。
1.1 数据校验框架的演变过程
1.1.1 JSR/Java 规范提案:BeanValidation
JSR:Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process) 提出新增一个标准化技术规范的正式请求。
任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
Bean Validation 是一个运行时的数据验证框架的标准,在验证之后验证的错误信息会被马上返回。
- BeanValidation就是这个JSR规范之一。
- 提到JSR,相信有小伙伴想去看下到底是个啥。可以看到:
- 规范从JSR 303 到 JSR 380;
- 目前最新规范是Bean Validation 2.0
- JSR # Bean Validation : https://jcp.org/en/jsr/summary?id=bean+validation
- JSR303是专家组成员向JCP提交的第1版Bean Validation,即针对bean数据校验提出的一个规范,使用注解方式实现数据校验。后面有升级版本JSR349及JSR380。各个版本的规范对应关系如下:
- JSR 380(Bean Validation 2.0)
- JSR380伴随着JAVAEE 8在2017年发布,完全兼容低版本的JAVA SE,Hibernate实现版本6.0.1.Final,Apache BVal实现版本2.0.3(不太确定)
- JSR 349(Bean Validation 1.1)
- JSR349伴随着JAVAEE 7在2013年发布,Hibernate实现版本5.1.1.Final,Apache BVal实现版本1.1.2
- 每一个注解都包含message字段,用于校验失败时作为提示信息,特殊的校验注解,如Pattern(正则校验),还可以自己添加正则表达式。
- JSR 303(Bean Validation 1.0)
-JSR303伴随着JAVAEE 6在2009年发布,Hibernate实现版本4.3.1.Final,Apache BVal实现版本0.5
- JSR 380(Bean Validation 2.0)
- 主流 Bean Validation 规范,使用 hibernate-validation 的实现。
- 如果使用 bean validation 2.0 规范,hibernate-validation 必须选择6.0.1以上版本
Bean Validation 2.0中包含了22个注解
- JSR / Bean Valiadation 与 Hibernate Validation、Spring Valiadation
- JSR规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,位于javax.validation.constraints包下,只提供规范不提供实现。
- 而hibernate validation是对这个规范的实践,提供相应的实现,并增加一些其他校验注解,如@Email,@Length,@Range等等,位于org.hibernate.validator.constraints包下。
- spring对hibernate validation进行二次封装,显示校验validated bean时,可以使用spring validation或hibernate validation;
- 而spring validation另一特性:便是其在springmvc模块中添加自动校验,并将校验信息封装进特定的类中。
1.1.2 JAVAX.VALIDATION.API
- Java 在2009年的 JAVAEE 6 中发布了 JSR303以及 javax 下的 validation 包内容。
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${javax.validation-api.version}</version>
</dependency>
重要版本
javax.validation:validation-api.version = 2.0.1.Final
spring-boot-starter-web/validation:2.1.4.RELEASE | hibernate-alidation:6.0.16.Final 中使用的 validation-api 为:
javax.validation:validation-api:2.0.1.Final
hibernate-alidation:6.0.16.Final 中使用的 validation-api 为:
javax.validation:validation-api:2.0.1.Final
- 这项工作的【主要目标】是为java应用程序开发人员提供 :
- 基于java对象的 约束(constraints)声明 ;
- 注:每个约束都有参数 message,groups 和 payload。这是 Bean Validation 规范的要求。
- 对约束的验证工具(validator);
- 约束元数据存储库和查询API;
- 默认实现;
- 基于java对象的 约束(constraints)声明 ;
- Java8开始,Java EE 改名为Jakarta EE。
- 故javax.validation相关的api在jakarta.validation的包下。因此:
- 大家看不同的版本的时候,会发现以前的版本包在
javax.validation
包下。 - 最新的版本包在
jakarta.validation
包下
- 大家看不同的版本的时候,会发现以前的版本包在
javase
的支持还在jcp(Java Community Process,Java社区标准过程),Java EE 改名 JakartaE E。- JakartaEE的官网及其支持的项目:
- 故javax.validation相关的api在jakarta.validation的包下。因此:
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>${jakarta.validation-api.version}</version>
</dependency>
重要版本
jakarta.validation:jakarta.validation-api.version = 2.0.2
spring-boot-starter-validation:2.3.12.RELEASE | hibernate-alidation:6.1.7.Final 使用的 validation-api 为:
jakarta.validation:jakarta.validation-api:2.0.2
- Bean Validation 2.0规范及默认实现:
1.1.3 HIBERNATE-VALIDATOR
- hibernate-validator是Hibernate项目中的一个数据校验框架,是Bean Validation 的参考实现;
- 【注意】
- 此处的 Hibernate 不是 Hibernate ORM,二者没有任何关系;
- hibernate-validator 和 hibernate orm 项目 均是 Hibernate 基金会(
org.hibernate
)下的项目之一。
- 【注意】
hibernate-validator
除了提供了JSR 303规范中所有内置constraint 的实现,还有一些附加的constraint。- 使用hibernate-validator能够将数据校验从业务代码中脱离出来,增加代码可读性;同时也让数据校验变得更加方便、简单。
- 项目官网:
- https://hibernate.org/validator/ |
- 项目官网
- http://hibernate.org/validator/documentation
- 官方文档
- https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/
- hibernate-validator的简介
- https://github.com/hibernate/hibernate-validator
- GitHub 源代码仓库
- https://hibernate.org/validator/ |
- 在Java语言中,
hibernate-validation
已成为【数据校验框架】实质上的标准框架的标准实现,再无其他框架可望其项背。
spring-boot-starter-web/validation:2.1.4.RELEASE | hibernate-alidation:6.0.16.Final
hibernate-alidation:6.0.16.Final
spring-boot-starter-validation:2.3.12.RELEASE | hibernate-alidation:6.1.7.Final
2 实践使用
2.1 基本使用步骤
Step1 编写实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
@NotBlank(message = "用户名不能为空")
private String name;
@NotBlank(message = "邮箱不能为空")
private String email;
}
Step2 引入依赖包(数据校验的标准框架及实现)
情况1:基于 javax.validation api
基于
javax.validation
api 的第三方库的有:
[1] javax.validation:validation-api : 2.0.1.Final
- [1] hibernate-alidation : 6.0.16.Final
- [2] spring-boot-starter-web/validation : 2.1.4.RELEASE
注:本组件依赖的hibernate-validation
的组件版本为 6.0.16.Final
<!-- | data validation framework | start -->
<!-- javax.validation-api : data validation api design standard & framework -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${javax.validation-api.version}</version>
</dependency>
<!-- hibernate-validator | http://hibernate.org/validator/documentation-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!-- org.glassfish:javax.el | hibernate-validator 依赖此组件,以防报错:"javax.validation.ValidationException: HV000183: Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead" --><dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>${glassfish.javax.el.version}</version>
</dependency>
<!-- | data validation framework | end -->
- 版本变量取值
- javax.validation-api.version = 2.0.1.Final
- hibernate-validator.version = 6.0.16.Final
- glassfish.javax.el.version = 3.0.1-b09
情况2:基于 jakarta.validation
api
基于
jakarta.validation
api 的第三方库的有:
[1] jakarta.validation : jakarta.validation-api : 2.0.2
- [1] hibernate-alidation : 6.1.7.Final
- [2] spring-boot-starter-validation : 2.3.12.RELEASE
注:本组件依赖的hibernate-validation
的组件版本为 6.1.7.Final
方式1
<!-- | data validation framework | start -->
<!-- jakarta.validation-api : data validation api design standard & framework -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>${jakarta.validation-api.version}</version>
</dependency>
<!-- hibernate-validator | http://hibernate.org/validator/documentation -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!-- org.glassfish:javax.el or org.glassfish:jakarta.el [recommend] (2选1即可) | hibernate-validator 依赖此组件,以防报错:"javax.validation.ValidationException: HV000183: Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead" -->
<!--
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>${glassfish.javax.el.version}</version>
</dependency> -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>${glassfish.jakarta.el.version}</version>
</dependency>
<!-- | data validation framework | end -->
- 版本变量取值
- jakarta.validation-api.version = 2.0.2
- hibernate-validator.version = 6.1.7.Final
- glassfish.javax.el.version = 3.0.1-b09 | glassfish.jakarta.el.version = 3.0.3
方式2:直接引用
spring-boot-starter-validation
<!-- | data validation framework | start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- | data validation framework | end -->
版本变量的取值
spring-boot.version := 2.3.12.RELEASE
由上可见:
[1]spring-boot-starter-validation
: 2.3.12.RELEASE
依赖hibernate-validation
: 6.1.7.Final
依赖org.glasssfish : jakarta.el
: 3.0.3
由上可见:
[1]hibernate-validation
: 6.1.7.Final
依赖了org.glasssfish : jakarta.el
(由于scope
是provided
,故具体版本未限制)
Step3 编写数据验证代码
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
//import org.hibernate.validator.HibernateValidator;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Student student = new Student("小明", null);
System.out.println(student);
//方式1
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
//方式2
//ValidatorFactory factory = Validation.byProvider( HibernateValidator.class ).configure()
//.addProperty( "hibernate.validator.fail_fast", "true" ) //true 快速失败返回模式 | false 普通模式
//.buildValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Student>> violations = validator.validate(student);
for (ConstraintViolation<Student> violation : violations) {
System.out.println(violation.getMessage());
}
}
}
output
Student(name=小明, email=null)
十一月 10, 2023 12:56:58 下午 org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 6.0.16.Final
邮箱不能为空
2.2 支持的POJO校验注解
2.2.1 javax/jakarta.validation 注解列表
在要校验的POJO上加上以下注解即可:
- 形如:
javax.validation.constraints.Email
注解 | 用途 |
---|---|
Valid (最常用的【标识注解】) | 递归的对关联的对象进行校验 标记用于验证级联的属性、方法参数或方法返回类型;在验证属性、方法参数或方法返回类型时,将验证在对象及其属性上定义的约束。此行为是递归应用的。 |
AssertFalse | 用于boolean字段,该字段的值只能为false |
AssertTrue | 用于boolean字段,该字段只能为true |
DecimalMax(value) | 被注释的元素必须是一个数字,只能大于或等于该值 |
DecimalMin(value) | 被注释的元素必须是一个数字,只能小于或等于该值 |
Digits(integer,fraction) | 检查是否是一种数字的(整数,小数)的位数 |
Future | 检查该字段的日期是否是属于将来的日期 |
FutureOrPresent | 判断日期是否是将来或现在日期 |
Past | 检查该字段的日期是在过去 |
PastOrPresent | 判断日期是否是过去或现在日期 |
Max(value) | 该字段的值只能小于或等于该值 |
Min(value) | 该字段的值只能大于或等于该值 |
Negative | 判断负数 |
NegativeOrZero | 判断负数或0 |
Positive | 判断正数 |
PositiveOrZero | 判断正数或0 |
NotNull | 不能为null |
Null | 必须为 null |
Pattern(value) @Pattern(regexp = ) |
被注释的元素必须符合指定的正则表达式 |
Size(max, min) | 检查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等 |
Length(max, min) | 判断字符串长度 |
CreditCardNumber | 被注释的字符串必须通过Luhn校验算法,银行卡,信用卡等号码一般都用Luhn计算合法性 |
被注释的元素必须是电子邮箱地址 | |
Length(min=, max=) | 被注释的字符串的大小必须在指定的范围内 |
NotBlank | 只能用于字符串不为null,并且字符串trim()以后length要大于0 |
NotEmpty | 集合对象的元素不为0,即集合不为空,也可以用于字符串不为null |
Range(min=, max=) | 被注释的元素必须在合适的范围内 |
SafeHtml | classpath中要有jsoup包 |
ScriptAssert | 要有Java Scripting API 即JSR 223("Scripting for the JavaTMPlatform")的实现 |
URL(protocol=,host=,port=,regexp=,flags=) | 被注释的字符串必须是一个有效的url |
- 注意
- @NotEmpty 用在集合类上面
- @NotBlank 用在String上面
- @NotNull 用在基本类型上
更多功能,如:自定义校验规则、分组校验、关联参数联合校验请查看官网文档。
2.2.2 springframework.validation 注解列表
- @Validated(spring) | 最常用的【标识注解】
- 包路径:
- org.springframework.validation.annotation.Validated
- spring 提供的扩展注解,可以方便的用于分组校验
- 其中,message 是提示消息,groups 可以根据情况来分组。
- 包路径:
2.2.3 样例
public class ParamTestDTO implements Serializable {
private static final long serialVersionUID = 7123882542534668217L;
@AssertTrue(message = "Error True")
private Boolean testTrue;
@AssertFalse(message = "Error False")
private Boolean testFalse;
@DecimalMax(value = "10", message = "Error StrMax")
private String testStrMax;
@DecimalMin(value = "1", message = "Error StrMin")
private String testStrMin;
@Max(value = 10, message = "Error Max")
private Integer testMax;
@Min(value = 1, message = "Error Min")
private Double testMin;
@Digits(integer = 2, fraction = 3, message = "Error Dig")
private BigDecimal testDig;
@Past(message = "Error Past")
private Date testPast;
@Future(message = "Error Future")
private Date testFuture;
@Null(message = "Error Null")
private String testNull;
@NotNull(message = "Error NonNull")
private String testNonNull;
@Pattern(regexp = "^[0-9]?[0-9]$", message = "Error Pattern")
private String testPattern;
@Size(min = 1, max = 10, message = "Error Size")
private List<String> testSize;
@Length(min = 1, max = 10, message = "Error Length")
private String testLength;
@NotBlank(message = "Error Blank")
private String testBlank;
@NotEmpty(message = "Error NotEmpty")
private String testEmpty;
@Range(min = 1, max = 10, message = "Error Range")
private String testRange;
}
2.3 应用场景
2.3.1 场景:Dubbo中使用Hibernate Validator校验入参
无需util,Dubbo接口配置上的validation为true即可。
- 在客户端验证参数
<dubbo:reference id="xxxService" interface="xxx.ValidationService" validation="true" />
- 在服务器端验证参数
<dubbo:service interface="xxx.ValidationService" ref="xxxService" validation="true" />
- 在代码里校验入参
//obj为包含Hibernate Validator注解的POJO
//快速失败模式
ValidResult validResult = ValidationUtil.fastFailValidate(obj);
//obj为包含Hibernate Validator注解的POJO
//全部校验模式
ValidResult validResult = ValidationUtil.allCheckValidate(obj);
2.3.2 场景:Web POST Api Controller
@RestController
public class StudentController {
// ...
@RequestMapping(value = "/addStudent",method = RequestMethod.POST)
public String addStudent(@Valid @RequestBody Student student){
System.out.println("student = [" + student + "]");
return "ok";
}
// ...
}
- 注意
- POST请求必须要加
@Valid
@Valid
注解:递归的对关联的对象进行校验
- 区分请求参数:@RequestBody 和 @RequestParam
- @RequestBody 获取的是请求体里面的数据,一般是前端传给后端的JSON字符串。
- @RequestParam 接收的是url里面的查询参数(比如xxxxxxx?name=admin)
- POST请求必须要加
2.3.3 场景:Web GET Api Controller
import org.springframework.validation.annotation.Validated;
@RestController
@Validated
public class StudentController {
//...
@RequestMapping(value = "/addStudent1",method = RequestMethod.GET)
public String addStudent1(@NotBlank(message = "name不能为空") String name){
System.out.println("name = [" + name + "]");
return "ok addStudent1";
}
//...
}
- Get请求需要在类上添加
@Validated
- org.springframework.validation.annotation.Validated
2.3.4 场景:优雅地返回校验信息
2.3.4.1 定义全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResultEntity handleBindException(MethodArgumentNotValidException ex) {
FieldError fieldError = ex.getBindingResult().getFieldError();
// 记录日志。。。
return ResultEntity.faill(211,fieldError.getDefaultMessage(),null);
}
}
2.3.4.2 定义校验失败返回模板
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultEntity<T> {
private Integer code;
private String message;
private T data;
public static <T> ResultEntity<T> faill(Integer code,String msg,T t){
return new ResultEntity<T>(code,msg,t);
}
}
2.3.5 场景:对象级联校验
- Student
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
@NotBlank(message = "用户名不能为空")
private String name;
@Max(150)
@Min(10)
@NotNull(message = "年龄不能为空")
private Integer age;
@Email
private String email;
@NotNull(message = "user不能为空")
@Valid
private User user;
}
- User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
@NotNull(message = "user对象中的username不能为空")
private String username;
}
2.3.6 场景:分组校验
如果同一个类,在不同的使用场景下有不同的校验规则,那么可以使用分组校验。实际需求,如未成年人是不能喝酒,如何校验?
public class Foo {
@Min(value = 18, groups = {Adult.class})
private Integer age;
public interface Adult { }
public interface Minor { }
}
@RequestMapping("/drink")
public String drink(@Validated({Foo.Adult.class}) Foo foo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
for (FieldError item : bindingResult.getFieldErrors()) {
}
return "fail";
}
return "success";
}
2.3.7 场景:自定义校验
作为示例,自定义校验注解@CannotHaveBlank
,实现字符串不能包含空格
的校验限制:
- 注解 CannotHaveBlank
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
// 自定义注解中指定这个注解真正的验证者类
@Constraint(validatedBy = {CannotHaveBlankValidator.class})
public @interface CannotHaveBlank {
// 默认错误消息
String message() default "不能包含空格";
// 分组
Class<?>[] groups() default {};
// 负载
Class<? extends Payload>[] payload() default {};
// 指定多个时使用
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface List {
CannotHaveBlank[] value();
}
}
- 接口 ConstraintValidator
public interface ConstraintValidator<A extends Annotation, T> {
void initialize(A constraintAnnotation);// 初始化事件方法
boolean isValid(T value, ConstraintValidatorContext context);// 判断是否合法
}
- 实现ConstraintValidator接口完成定制校验逻辑的类 : CannotHaveBlankValidator
// 所有的验证者都需要实现ConstraintValidator接口
public class CannotHaveBlankValidator implements ConstraintValidator<CannotHaveBlank, String> {
@Override
public void initialize(CannotHaveBlank constraintAnnotation) {
//...
}
@Override
// ConstraintValidatorContext包含认证中所有的信息,
// 获取默认错误提示信息,禁用错误提示信息,改写错误提示信息等操作。
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value != null && value.contains(" ")) {
//获取默认提示信息
String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate();
System.out.println("default message :" + defaultConstraintMessageTemplate);
//禁用默认提示信息
context.disableDefaultConstraintViolation();
//设置提示语
context.buildConstraintViolationWithTemplate("can not contains blank").addConstraintViolation();
return false;
}
return true;
}
}
2.3.8 场景:统一格式化输出
在验证数据时,常常需要给用户告知错误信息。通常情况下,错误信息都是非常简短的。为了更好的告知用户错误信息,validation-api提供了一种非常好的机制来格式化错误信息。
以一个使用validation-api对错误信息进行格式化为例子:
public static String validateAndFormat(T obj) {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set> constraintViolationSet = validator.validate(obj);
if (constraintViolationSet != null && constraintViolationSet.size() > 0) {
StringBuilder sb = new StringBuilder();
for (ConstraintViolation constraintViolation : constraintViolationSet) {
sb.append(constraintViolation.getPropertyPath()).append(":").append(constraintViolation.getMessage()).append(",");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
} else {
return "";
}
}
首先使用validator.validate(obj)方法对数据进行验证;
如果有错误信息,则用StringBuilder将错误信息格式化后返回。
2.4 小结:Hibernate-Validator 校验模式
2.4.1 普通模式
默认模式
- 首先,校验完所有的属性;
- 然后,返回所有的验证失败信息。
2.4.2 快速失败返回模式
只要有一个失败就立马返回
- 开启快速失败返回模式
@Configuration
public class HibernateValidatorConfiguration {
@Bean
public Validator validator(){
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
// true 快速失败返回模式 false 普通模式
.addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}
测试验证不通过就会抛出 ConstraintViolationException 异常,和之前普通模式下抛出的异常不一样。
所以,为了格式统一还需要自定义的异常处理。
2.4.3 全局异常处理
// 开启快速失败返回模式,GET请求校验不通过会抛出如下异常,在这对它处理
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResultEntity handle(ValidationException exception) {
if (exception instanceof ConstraintViolationException) {
ConstraintViolationException exs = (ConstraintViolationException) exception;
Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
for (ConstraintViolation<?> item : violations) {
System.out.println(item.getMessage());
return ResultEntity.faill(212, item.getMessage(), null);
}
}
return ResultEntity.faill(212, "abc", null);
}
X 参考与推荐文献
- JSR # Bean Validation :
- Jakarta (Java EE)
- 项目官网:
- https://hibernate.org/validator/ 【推荐】
- 项目官网
- http://hibernate.org/validator/documentation 【推荐】
- 官方文档
- https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/
- hibernate-validator的简介
- https://github.com/hibernate/hibernate-validator
- GitHub 源代码仓库
- https://hibernate.org/validator/ 【推荐】
- Hibernate-Validator(数据校验框架) - CSDN
- Hibernate Validator—更简洁的参数校验及一个util - segmentfault
- Hibernate validation "Unable to initialize javax.el.ExpressionFactory" error - stackoverflow
- SPRINGBOOT项目后端表单验证(JAVAX.VALIDATION.API与HIBERNATE-VALIDATOR) - 灰信网 【推荐】
- 在springboot项目中,结合springAOP和AspectJ,实现通过自定义注解(
@BeanValidation
) + 自定义注解处理方法(Object validateParamByAnnotation(ProceedingJoinPoint ponit, BeanValidation beanValidation)
)的方式进行数据格式验证。
- 在springboot项目中,结合springAOP和AspectJ,实现通过自定义注解(
- 数据校验validation - CSDN
- 【深度思考】如何优雅的校验参数? - Zhihu
[数据校验/数据质量] 数据校验框架:hibernate-validation的更多相关文章
- 学习Spring Boot:(十)使用hibernate validation完成数据后端校验
前言 后台数据的校验也是开发中比较注重的一点,用来校验数据的正确性,以免一些非法的数据破坏系统,或者进入数据库,造成数据污染,由于数据检验可能应用到很多层面,所以系统对数据校验要求比较严格且追求可变性 ...
- (转)struts2:数据校验,通过XWork校验框架实现(validation.xml)
转载自:http://www.cnblogs.com/nayitian/p/3475661.html struts2:数据校验,通过XWork校验框架实现(validation.xml) 根据输入 ...
- struts2:数据校验,通过XWork校验框架实现(validation.xml)
根据输入校验的处理场所的不同,可以将输入校验分为客户端校验和服务器端校验两种.服务器端验证目前有两种方式: 第一种: 参考:struts2:数据校验,通过Action中的validate()方法实现校 ...
- 【SpringMVC】SpringMVC系列12之数据类型转换、格式化、校验
12.数据类型转换.格式化.校验 12.1.数据绑定流程 Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFacto ...
- Spring MVC—数据绑定机制,数据转换,数据格式化配置,数据校验
Spring MVC数据绑定机制 数据转换 Spring MVC处理JSON 数据格式化配置使用 数据校验 数据校验 Spring MVC数据绑定机制 Spring MVC解析JSON格式的数据: 步 ...
- 天气类API调用的代码示例合集:全国天气预报、实时空气质量数据查询、PM2.5空气质量指数等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 全国天气预报:数据来自国家气象局,可根据地名.经纬度GPS.IP查 ...
- python爬取《龙岭迷窟》的数据,看看质量剧情还原度到底怎么样
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:简单 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行 ...
- Struts2内建校验器(基于校验框架的文件校验)
位于xwork-2.0.4.jar压缩包中( com.opensymphony.xwork2.validator.validators)有个文件default.xml ,该文件中定义了Struts2框 ...
- GPS数据包格式及数据包解析
GPS数据包解析 GPS数据包解析 目的 GPS数据类型及格式 数据格式 数据解释 解析代码 结构体定义 GPRMC解析函数 GPGGA解析函数 测试样例输出 gps数据包格式 gps数据解析 车联网 ...
- spring-boot 使用hibernate validation对参数进行优雅的校验
springboot天生支持使用hibernate validation对参数的优雅校验,如果不使用它,只能对参数挨个进行如下方式的手工校验,不仅难看,使用起来还很不方便: if(StringUtil ...
随机推荐
- 详解TCP网络协议栈的工作原理
本文分享自华为云社区<网络通信的神奇之旅:解密Linux TCP网络协议栈的工作原理>,作者: Lion Long . 一.TCP网络开发API TCP,全称传输控制协议(Transmis ...
- 为什么Python是数据科学家的首选语言
这篇文章全面探讨了Python作为数据科学领域首选语言的原因.从Python的历史.特性,到在数据科学中的应用实例,再到与其他数据科学语言的比较,以及在实际企业中的应用,我们深入剖析了Python的优 ...
- 策略模式+Spring配置类优化多if..else思路
图示 1. 现状 场景: 假设设备上报不同类型的消息,我们要对不同类型的消息做不同的处理.如果我们通过if..else的方式处理的话会显得比较冗余. 例如: if("alarmEvent&q ...
- node: #!/usr/bin/env node
声明 windows中不支持Shebang,它是通过文件的扩展名来确定使用什么解释器来执行脚本 参考链接: https://juejin.cn/post/6844903826344902670
- 通过 tree shaking 移除无用代码
tree shaking 依赖于ES Module 的静态语法分析,在项目编译时移除无用的代码以减少文件体积. usedExports 在文件中,我们可能定义了变量但是暂时又没有用到,这样会造成空间的 ...
- 1. 通俗易懂的Redis基础
通俗易懂的Redis基础教程(基于CentOS 7) 目录 通俗易懂的Redis基础教程(基于CentOS 7) 1 Redis是什么 1.1 NoSQL概念 1.2 NoSQL与SQL比较 1.3 ...
- 【译】摇摆你的调试游戏:你需要知道的 Parallel Stack Window 小知识!
在 Visual Studio 2022 17.6和17.7中,我们在 Parallel Stack 窗口中添加了大量新功能,可以将您的多线程调试提升到一个新的水平. 但是 Parallel Stac ...
- RocketMQ系列(一) 基本介绍
RocketMQ系列(一) 基本介绍 1.MQ 作用 MQ 的应用场景主要包含以下 3 个方面: 1.1.异步与解耦 当我们下了一个订单之后,订单服务会进行 RPC 同步调用 支付服务.库存服务.物流 ...
- 代码随想录算法训练营第二十八天| 93.复原IP地址 78.子集 90.子集II
93.复原IP地址 卡哥建议:本期本来是很有难度的,不过 大家做完 分割回文串 之后,本题就容易很多了 题目链接/文章讲解:https://programmercarl.com/0093.%E5% ...
- Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.so
在安装Docker以后,执行命令出现错误. Got permission denied while trying to connect to the Docker daemon socket at u ...