Hibernate Validator 组件

news/2025/1/13 2:46:46/

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检查是否是一个有效的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;
}

创建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不能为nullreturn "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` 注解一起使用,以提供全局的异常处理、数据绑定和数据预处理逻辑。

主要功能如下:

  1. 异常处理:通过在 @ControllerAdvice 注解的类中定义 @ExceptionHandler 注解的方法,可以捕获和处理控制器中抛出的异常。这样可以实现统一的异常处理逻辑,避免在每个控制器中重复编写异常处理代码。
  2. 数据绑定:通过在 @ControllerAdvice 注解的类中定义 @InitBinder 注解的方法,可以实现对请求数据的统一绑定和预处理。这样可以集中处理一些通用的数据绑定逻辑,例如日期格式化、参数验证等。
  3. 全局数据预处理:通过在 @ControllerAdvice 注解的类中定义 @ModelAttribute 注解的方法,可以在所有控制器方法执行之前,预先加载一些共享的模型数据。这样可以避免在每个控制器方法中重复加载相同的模型数据。

使用 @ControllerAdvice 注解可以实现全局的异常处理和数据绑定,使代码更加简洁、可维护,并且提供了统一的控制器层面的处理逻辑。它可以让开发人员集中处理一些通用的需求,减少重复代码的编写,提高开发效率。

需要注意的是,@ControllerAdvice 注解默认只作用于被 @Controller@RestController 注解的类上。如果要扩展其作用范围,可以使用 basePackagesbasePackageClasses 属性来指定要扫描的包或类。

优化

通过控制台的输出可以看到,即使有一个字段校验不通过,校验框架也会将我们的多个属性都进行了数据校验(默认行为),如果我们希望只要有一个属性校验失败就直接返回提示信息,后面的属性不再进行校验了该如何实现呢?

创建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 {@Beanpublic Validator validator() {ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()//快速失败返回模式.addProperty("hibernate.validator.fail_fast", "true").buildValidatorFactory();return validatorFactory.getValidator();}/*** 开启快速返回* 如果参数校验有异常,直接抛异常,不会进入到 controller,使用全局异常拦截进行拦截*/@Beanpublic MethodValidationPostProcessor methodValidationPostProcessor() {MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();/**设置validator模式为快速失败返回*/postProcessor.setValidator(validator());return postProcessor;}
}

注意:上面创建的类并不是配置类,所以到目前为止快速失败返回模式并不会生效,为了使其生效需要创建一个注解用于控制此模式的开启

创建注解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);}
}

通过控制台的输出可以看到,虽然我们输入的数据有多个都不符合校验规则,但是只有一个校验失败异常信息,这说明已经开启了快速失败返回模式。
参考:传智播客相关公开笔记


http://www.ppmy.cn/news/666547.html

相关文章

IDEA开发插件的相关参考

教程 用gradle开发IDEA插件_idea gradle插件_ykdsg的博客-CSDN博客 5分钟从零开发一款简易的IDEA插件 ※通过gradle开发idea插件&#xff0c;环境版本适配_wl1411956542的博客-CSDN博客 技术调研&#xff0c;IDEA 插件怎么开发「脚手架、低代码可视化编排、接口生成测试」&…

苹果手机自制铃声

把文件拖到资料库&#xff0c;或者点击文件-将文件添加到资料库 点击菜单栏下面的 音乐 图标&#xff0c;右键点击刚刚添加的音乐文件名称——显示简介——选项&#xff1a;设置铃声开始与结束时间&#xff0c;长度不能超过40秒&#xff0c;确认&#xff1b; 左侧菜单栏切换到歌…

panic 苹果aop_iPhone重启故障 iOS日志分析

iPhone重启故障 iOS日志分析 Panic Full文件里面记录了iPhone重启原因,根据对日志数据的分析,我们能得到一些故障信息,以此判断出是哪个硬件导致的问题。 进入手机设置 – 通用-隐私-分析-数据,找到对应时间的重启文件,Panic Full开头的文件,如Panic Full – 2020/02/25 …

Apple Push Notification Service(苹果推送服务)

https://developer.apple.com/library/IOS/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html Apple Push Notification Service 苹果推送服务 Apple Push Notification service (APNs for short) is the centerpiece of t…

java苹果推送_iphone 推送通知 java 实现

前提准备, 在编写push notification之获取device token中拿到device token以后,需要把token字符串发送给应用的服务器端,即provider。 对于越狱手机获取不到 device token的可以通过cydia安装pushdoctor,安装方法可以google一下在这就不多说了,我的越狱手机通过安装push补…

ios12怎么滑屏解锁_对比苹果iOS12和安卓9.0,相互学习了哪些功能

上周&#xff0c;安卓最新版安卓9.0已经推送了正式版本&#xff0c;而iOS12也已经发布了Beta7&#xff0c;无限接近于正式版。如无意外&#xff0c;在九月份&#xff0c;无论是安卓还是iOS&#xff0c;都会完成今年的系统例行换代。 而出乎人们意料但又在情理之中的是&#xff…

android 手机设置按钮声音,安卓P音量键默认控制媒体音量的真相,这里有答案!...

原标题:安卓P音量键默认控制媒体音量的真相,这里有答案! 对于手机界来说下半年最大的期待就是安卓第九代系统Android P(俗称安卓9.0)的发布。在8月份谷歌正式发布之后,用户翘首以盼希望能尽快体验,随后华为、小米、一加等厂商纷纷开启了安卓9.0的定制适配进程,华为EMUI9.…

苹果七怎么分屏_安卓党入第一次入苹果,说说使用感受~

7月初在毒入了苹果11. 等了6天吧。&#xff08;我选的还是极速&#xff0c;快递应该叫龟峰吧~&#xff09; 买之前也是各种纠结选择。后来对象说我一直好奇&#xff0c;这次就试一试呗。&#xff08;对&#xff0c;就是好奇大家所说的原生态&#xff0c;还有相机真实感以及可以…