gst*_*low 94 java validation hibernate hibernate-validator maven
我尝试使用hibernate验证器编写非常简单的应用程序:
我的步骤:
在pom.xml中添加以下依赖项:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.1.Final</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
写代码:
class Configuration {
Range(min=1,max=100)
int threadNumber;
//...
public static void main(String[] args) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Configuration configuration = new Configuration();
configuration.threadNumber = 12;
//...
Set<ConstraintViolation<Configuration>> constraintViolations = validator.validate(configuration);
System.out.println(constraintViolations);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到以下stacktrace:
Exception in thread "main" javax.validation.ValidationException: Unable to instantiate Configuration.
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:279)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
...
at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:110)
at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:86)
at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:41)
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:276)
... 2 more
Run Code Online (Sandbox Code Playgroud)
我错了什么?
gst*_*low 149
添加到pom.xml以下依赖项后它正在工作:
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
Bru*_*uno 56
做的
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
wal*_*ros 15
如果您使用tomcat作为服务器运行时并且在测试中遇到此错误(因为测试期间tomcat运行时不可用),那么包含tomcat el运行时而不是glassfish中的运行时是有意义的.这将是:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-el-api</artifactId>
<version>8.5.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>8.5.14</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
her*_*rau 11
关于Hibernate验证器文档页面,您必须定义对JSR-341实现的依赖关系:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b11</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
Bas*_*que 11
作为从Oracle向Eclipse 基金会移交的一部分,Java EE将更名为Jakarta EE。在 Jakarta EE 9 中,Java 包名称从 更改javax.*为jakarta.*.
M. Justin对于雅加达的回答是正确的。我添加这个答案是为了提供更多解释和具体示例。
Jakarta Validation(以前称为Jakarta Bean Validation)是 Java 中 API 的规范。此规范的二进制库仅包含接口,而不包含可执行代码。所以我们还需要这些接口的实现。
我只知道Jakarta Validation版本 2 和 3 规范的一种实现:Hibernate Validator版本 6 和 7(分别)。
对于 Web 应用程序,符合 Jakarta 标准的 Web 容器将提供执行 Bean 验证所需的接口和实现。
对于桌面和控制台应用程序,我们没有这样的符合 Jakarta 标准的 Web 容器。因此,您必须将接口jar和实现 jar 与您的应用程序捆绑在一起。
您可以使用Maven、Gradle或Ivy等依赖管理工具来下载并捆绑接口和实现 jar。
要运行Jakarta Bean Validation,我们还需要另一个 Jakarta 工具:Jakarta Expression Language,一种用于嵌入和评估表达式的专用编程语言。雅加达表达式语言也简称为EL。
Jakarta 表达式语言由 Jakarta EE 定义为一种规范,您必须下载一个 jar 接口。并且您还需要在另一个 jar 中获取这些接口的实现。
您可以选择多种实现。截至 2021 年 3 月,我知道Eclipse Foundation 提供了Eclipse Glassfish作为独立库的实现,我们可以免费下载。可能还有其他实现,例如IBM Corporation 的Open Liberty 。货比三家,寻找适合您需求的实施方案。
将所有这些信息放在一起,您需要四个 jar: Jakarta Validation和Jakarta Expression Language两个项目各一对接口和实现 jar 。
如果 Maven 是您选择的工具,那么以下是您需要添加到 Maven POM 文件中的四个依赖项。
如上所述,您也许可以找到另一种 EL 实现来替代我在这里使用的 Glassfish 库。
<!--********| Jakarta Validation |********-->
<!-- Interface -->
<!-- https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.0</version>
</dependency>
<!-- Implementation -->
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.1.Final</version>
</dependency>
<!-- Jakarta Expression Language -->
<!-- Interface -->
<!-- https://mvnrepository.com/artifact/jakarta.el/jakarta.el-api -->
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>4.0.0</version>
</dependency>
<!-- Implementation -->
<!-- https://mvnrepository.com/artifact/org.glassfish/jakarta.el -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>4.0.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这应该消除javax.validation.ValidationException: HV000183: Unable to load 'javax.el.ExpressionFactory'错误。
您可以使用以下简单的类来测试您的设置Car。我们对三个成员字段中的每一个都进行了验证。
package work.basil.example.beanval;
import jakarta.validation.constraints.*;
public class Car
{
// ---------------| Member fields |----------------------------
@NotNull
private String manufacturer;
@NotNull
@Size ( min = 2, max = 14 )
private String licensePlate;
@Min ( 2 )
private int seatCount;
// ---------------| Constructors |----------------------------
public Car ( String manufacturer , String licensePlate , int seatCount )
{
this.manufacturer = manufacturer;
this.licensePlate = licensePlate;
this.seatCount = seatCount;
}
// ---------------| Object overrides |----------------------------
@Override
public String toString ( )
{
return "Car{ " +
"manufacturer='" + manufacturer + '\'' +
" | licensePlate='" + licensePlate + '\'' +
" | seatCount=" + seatCount +
" }";
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果使用 Java 16 及更高版本,请改用更简短的内容record。
package work.basil.example.beanval;
import jakarta.validation.constraints.*;
public record Car (
@NotNull
String manufacturer ,
@NotNull
@Size ( min = 2, max = 14 )
String licensePlate ,
@Min ( 2 )
int seatCount
)
{
}
Run Code Online (Sandbox Code Playgroud)
运行验证。首先我们运行一个成功配置的Car对象。然后我们实例化第二个Car有缺陷的对象,违反了三个字段中每一个字段的一个约束。
package work.basil.example.beanval;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set;
public class App
{
public static void main ( String[] args )
{
App app = new App();
app.demo();
}
private void demo ( )
{
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
// No violations.
{
Car car = new Car( "Honda" , "ABC-789" , 4 );
System.out.println( "car = " + car );
Set < ConstraintViolation < Car > > violations = validator.validate( car );
System.out.format( "INFO - Found %d violations.\n" , violations.size() );
}
// 3 violations.
{
Car car = new Car( null , "X" , 1 );
System.out.println( "car = " + car );
Set < ConstraintViolation < Car > > violations = validator.validate( car );
System.out.format( "INFO - Found %d violations.\n" , violations.size() );
violations.forEach( carConstraintViolation -> System.out.println( carConstraintViolation.getMessage() ) );
}
}
}
Run Code Online (Sandbox Code Playgroud)
运行时。
car = Car{ manufacturer='Honda' | licensePlate='ABC-789' | seatCount=4 }
INFO - Found 0 violations.
car = Car{ manufacturer='null' | licensePlate='X' | seatCount=1 }
INFO - Found 3 violations.
must be greater than or equal to 2
must not be null
size must be between 2 and 14
Run Code Online (Sandbox Code Playgroud)
如果您将Spring Boot与启动程序一起使用-此依赖项会同时添加tomcat-embed-el和hibernate-validator依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
如果你不需要javax.el(例如在JavaSE的应用程序),使用ParameterMessageInterpolator从Hibernate的验证。Hibernate验证器是一个独立的组件,无需Hibernate本身即可使用。
依赖于休眠验证器
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
使用ParameterMessageInterpolator
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;
private static final Validator VALIDATOR =
Validation.byDefaultProvider()
.configure()
.messageInterpolator(new ParameterMessageInterpolator())
.buildValidatorFactory()
.getValidator();
Run Code Online (Sandbox Code Playgroud)
Hibernate Validator 需要——但不包括——表达式语言 (EL)实现。添加对一个的依赖将解决这个问题。
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>3.0.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
此要求记录在Hibernate Validator 入门文档中。在 Java EE 环境中,它将由容器提供。在像您这样的独立应用程序中,需要提供它。
Hibernate Validator 还需要统一表达式语言 ( JSR 341 ) 的实现来评估约束违反消息中的动态表达式。
当您的应用程序在 Java EE 容器(例如WildFly )中运行时,容器已经提供了 EL 实现。
但是,在 Java SE 环境中,您必须将实现作为依赖项添加到 POM 文件中。例如,您可以添加以下依赖项以使用 JSR 341 参考实现:
Run Code Online (Sandbox Code Playgroud)<dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.el</artifactId> <version>${version.jakarta.el-api}</version> </dependency>
存在几种 EL 实现。一种是文档中提到的 Jakarta EE Glassfish参考实现。另一个是嵌入式Tomcat,当前版本的Spring Boot默认使用它。该版本的 EL 可以按如下方式使用:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>9.0.48</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
如本评论中所述,必须选择表达式语言的兼容版本。Glassfish 实现被指定为Hibernate Validator提供的-scope 依赖项,因此那里指定的版本应该可以正常工作。特别是,Hibernate Validator 7使用 Glassfish EL 实现的第 4 版,而Hibernate 6使用第 3 版。
在 Spring Boot 项目中,spring-boot-starter-validation通常会使用依赖项,而不是直接指定 Hibernate 验证器和 EL 库。该依赖项包括org.hibernate.validator:hibernate-validator和tomcat-embed-el。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.4.3.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
92252 次 |
| 最近记录: |