Hibernate Validator 组件介绍
Hibernate Validator 是一个基于 Java 的验证框架,它提供了强大且灵活的验证功能,用于验证 JavaBean 对象的状态。它是基于 JSR 380 规范(Bean Validation 2.0)的实现,并且可以与任何 Java 应用程序集成。
Hibernate Validator 的目标是提供一种方便、易于使用的验证机制,以确保数据的完整性和一致性。它可以用于验证表单输入、数据传输对象(DTO)、实体对象等各种类型的数据。
该框架通过注解和配置文件来定义验证规则,包括常见的验证约束,如非空、长度限制、正则表达式匹配等。它还提供了一组内置的验证注解,例如 @NotNull
、@NotEmpty
、@Size
、@Pattern
等。
除了基本的验证约束之外,Hibernate Validator 还支持自定义验证约束,以满足特定应用程序的需求。通过编写自定义验证器和约束注解,开发人员可以定义和应用自己的验证规则。
Hibernate Validator 还提供了多种验证结果的处理方式,包括返回验证错误信息的集合、抛出异常或执行自定义操作。这使得在验证失败时能够采取适当的措施,例如显示错误消息、回滚事务等。
校验参数基本上是一个体力活,而且冗余代码繁多,也影响代码的可读性,我们需要一个比较优雅的方式来解决这个问题。Hibernate Validator 框架刚好解决了这个问题,可以以很优雅的方式实现参数的校验,让业务代码和校验逻辑分开,不再编写重复的校验逻辑。
hibernate-validator优势:
-
验证逻辑与业务逻辑之间进行了分离,降低了程序耦合度
-
统一且规范的验证方式,无需你再次编写重复的验证代码
-
你将更专注于你的业务,将这些繁琐的事情统统丢在一边
hibernate-validator的maven坐标:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
hibernate-validator常用注解
hibernate-validator提供的校验方式为在类的属性上加入相应的注解来达到校验的目的。hibernate-validator提供的用于校验的注解如下:
注解 | 说明 |
---|---|
@AssertTrue | 用于boolean字段,该字段只能为true |
@AssertFalse | 用于boolean字段,该字段只能为false |
@CreditCardNumber | 对信用卡号进行一个大致的验证 |
@DecimalMax | 只能小于或等于该值 |
@DecimalMin | 只能大于或等于该值 |
检查是否是一个有效的email地址 | |
@Future | 检查该字段的日期是否是属于将来的日期 |
@Length(min=,max=) | 检查所属的字段的长度是否在min和max之间,只能用于字符串 |
@Max | 该字段的值只能小于或等于该值 |
@Min | 该字段的值只能大于或等于该值 |
@NotNull | 不能为null |
@NotBlank | 不能为空,检查时会将空格忽略 |
@NotEmpty | 不能为空,这里的空是指空字符串 |
@Pattern(regex=) | 被注释的元素必须符合指定的正则表达式 |
@URL(protocol=,host,port) | 检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件 |
hibernate-validator入门实战
配置pom.xml文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>cn.itcast</groupId>
<artifactId>hibernate-validator_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--
spring-boot-starter-web中已经依赖了hibernate-validator
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
-->
</dependencies>
创建User类
package com.example.entiry;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.*;
@Data
public class User {
@NotNull(message = "id不能为空!")
private Integer id;
@NotEmpty(message = "用户名不能为空!")
@Length(message = "用户名最长为20",max = 20)
private String username;
@Email(message = "邮箱格式不正确")
private String email;
@Max(message = "最大为150",value = 150)
@Min(message = "最小为1",value = 1)
private Integer age;
}
验证Bean是否符合要求
@Test
public void init(){
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
User user = new User();
Set<ConstraintViolation<User>> validate = validator.validate(user);
// 如果验证通过则set集合为空
if (validate.size() > 0){
validate.forEach(v->{System.out.println(v.getMessage());});
}else {
System.out.println("验证通过");
}
}
创建UserController
package com.example.controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.entiry.User;
import javax.validation.constraints.NotNull;
@RestController
@RequestMapping("/user")
@Validated //开启hibernate-validator 校验
public class UserController {
//简单类型校验
@RequestMapping("/delete")
public String delete(@NotNull Integer id){ //要求id不能为null
return "delete success";
}
//对象属性校验
@RequestMapping("/save")
public String save(@Validated User user){ //验证user是否符合定义的规范
System.out.println("save..." + user);
return "OK";
}
}
创建启动类
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HibernateValidatorApp {
public static void main(String[] args) {
SpringApplication.run(HibernateValidatorApp.class,args);
}
}
启动
如果传入的数据不符合校验规则,则浏览器访问地址:http://localhost:8080/user/save 页面直接报错;其实这对于用户来说是不友好的,因此需要对异常信息进行统一处理再以一种友好的提示反馈到前端;
创建全局异常处理类
package com.example.config;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;
@ResponseBody
@ControllerAdvice(annotations = {RestController.class, Controller.class}) //括号中的是切片,表示只处理这两个标识类的异常
public class ExceptionConfiguration {
//异常处理方法
@ExceptionHandler({ConstraintViolationException.class, BindException.class}) //异常处理器,表示只抓取括号中的
// 验证异常和数据绑定异常,凡事上面括号中的指定的类的具体异常都由此方法进行处理,参数由容器提供;
public String exceptionHanlder(Exception ex, HttpServletRequest request){
String msg = "";
if(ex instanceof ConstraintViolationException){
ConstraintViolationException constraintViolationException = (ConstraintViolationException)ex;
ConstraintViolation<?> next = constraintViolationException.getConstraintViolations().iterator().next();
msg = next.getMessage();
} else if (ex instanceof BindException) {
BindException bindException = (BindException) ex;
msg = bindException.getBindingResult().getFieldError().getDefaultMessage();
}
return msg;
}
}
@ControllerAdvice 是 Spring MVC 提供的一个注解,用于统一处理控制器(Controller)中的异常和全局数据绑定。
@ControllerAdvice注解通常与
@ExceptionHandler、
@InitBinder和
@ModelAttribute` 注解一起使用,以提供全局的异常处理、数据绑定和数据预处理逻辑。
主要功能如下:
- 异常处理:通过在
@ControllerAdvice
注解的类中定义@ExceptionHandler
注解的方法,可以捕获和处理控制器中抛出的异常。这样可以实现统一的异常处理逻辑,避免在每个控制器中重复编写异常处理代码。 - 数据绑定:通过在
@ControllerAdvice
注解的类中定义@InitBinder
注解的方法,可以实现对请求数据的统一绑定和预处理。这样可以集中处理一些通用的数据绑定逻辑,例如日期格式化、参数验证等。 - 全局数据预处理:通过在
@ControllerAdvice
注解的类中定义@ModelAttribute
注解的方法,可以在所有控制器方法执行之前,预先加载一些共享的模型数据。这样可以避免在每个控制器方法中重复加载相同的模型数据。
使用 @ControllerAdvice
注解可以实现全局的异常处理和数据绑定,使代码更加简洁、可维护,并且提供了统一的控制器层面的处理逻辑。它可以让开发人员集中处理一些通用的需求,减少重复代码的编写,提高开发效率。
需要注意的是,@ControllerAdvice
注解默认只作用于被 @Controller
或 @RestController
注解的类上。如果要扩展其作用范围,可以使用 basePackages
或 basePackageClasses
属性来指定要扫描的包或类。
优化
通过控制台的输出可以看到,即使有一个字段校验不通过,校验框架也会将我们的多个属性都进行了数据校验(默认行为),如果我们希望只要有一个属性校验失败就直接返回提示信息,后面的属性不再进行校验了该如何实现呢?
创建ValidatorConfiguration类,指定校验时使用快速失败返回模式
package com.example.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
public class ValidatorConfiguration {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory =
Validation.byProvider(HibernateValidator.class)
.configure()
//快速失败返回模式
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
return validatorFactory.getValidator();
}
/**
* 开启快速返回
* 如果参数校验有异常,直接抛异常,不会进入到 controller,使用全局异常拦截进行拦截
*/
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor =
new MethodValidationPostProcessor();
/**设置validator模式为快速失败返回*/
postProcessor.setValidator(validator());
return postProcessor;
}
}
注意:上面创建的类并不是配置类,所以到目前为止快速失败返回模式并不会生效,为了使其生效需要创建一个注解用于控制此模式的开启文章来源:https://www.toymoban.com/news/detail-514496.html
创建注解EnableFormValidator用于控制快速失败返回模式的开启
package com.example.config;
import org.springframework.context.annotation.Import;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 在启动类上添加该注解来启动表单验证功能---快速失败返回模式
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ValidatorConfiguration.class)
public @interface EnableFormValidator {
}
在启动类上加入EnableFormValidator注解,开启快速失败返回模式
package com.example;
import cn.itcast.config.EnableFormValidator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableFormValidator
public class HibernateValidatorApp {
public static void main(String[] args) {
SpringApplication.run(HibernateValidatorApp.class,args);
}
}
通过控制台的输出可以看到,虽然我们输入的数据有多个都不符合校验规则,但是只有一个校验失败异常信息,这说明已经开启了快速失败返回模式。 参考:传智播客相关公开笔记
文章来源地址https://www.toymoban.com/news/detail-514496.html
到了这里,关于Hibernate Validator 组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!