天道酬勤,学无止境

如果@Constraint(validated by = {}),则休眠验证器验证约束(Hibernate validator to validate constraints if @Constraint(validated by = {}))

问题

我有一个使用休眠验证器进行验证的 Spring Web 应用程序。 我有位于不同项目中的约束注释。 我需要在我的 spring 项目中为这些约束设置验证器,因为我需要一些服务来执行验证。 所以情况是:我不能将我的约束验证器放在 @Constraint(validatedBy = MyConstraintValidator.class) 因为验证器在不同的项目中,我不能添加依赖,因为这会创建一个循环依赖,这不是我们的方式想要它。 我注意到 javax.constraints 没有指定验证器,它只是 @Constraint(validatedBy= {})。 但是休眠验证器仍然知道如何验证它们。 有没有办法告诉我的休眠验证器如何在不指定约束验证器的情况下验证我的约束?

我希望能够验证这个约束:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Constraint(validatedBy = {})
public @interface OneOf {

    String message() default "{OneOf}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

谢谢!

回答1

javax.validation.constraints将验证器留给实现。 Hibernate 为这些约束提供验证器,并在引导时注册它们。

您可以通过 XML 设置验证器,而无需使用@Constraint(validatedBy = { }) 。 但是,这通常用于使用您自己的验证器添加/替换提供的验证器。 我不确定它会如何帮助你,因为你仍然需要引用约束验证器。

使用 XML 约束定义的示例:

<constraint-definition annotation="org.mycompany.CheckCase">
    <validated-by include-existing-validators="false">
        <value>org.mycompany.CheckCaseValidator</value>
    </validated-by>
</constraint-definition>

请参阅:通过 XML 配置

即将发布的 5.2 版本提供了更多方法,例如使用服务加载器或实现ConstraintDefinitionContributor 。 请参阅:提供约束定义

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 原始集合的休眠验证(Hibernate Validation of Collections of Primitives)
    问题 我希望能够执行以下操作: @Email public List<String> getEmailAddresses() { return this.emailAddresses; } 换句话说,我希望列表中的每个项目都可以作为电子邮件地址进行验证。 当然,这样注释一个集合是不可接受的。 有没有办法做到这一点? 回答1 JSR-303和Hibernate Validator都没有任何可以约束Collection每个元素的现成约束。 解决此问题的一种可能解决方案是创建自定义@ValidCollection约束和相应的验证程序实现ValidCollectionValidator 。 为了验证集合的每个元素,我们需要在ValidCollectionValidator内部有一个Validator实例; 为了得到这样的实例,我们需要ConstraintValidatorFactory自定义实现。 看看您是否喜欢以下解决方案... 简单地, 复制并粘贴所有这些Java类(并导入relavent类); 在类路径上添加validation-api,hibenate-validator,slf4j-log4j12和testng jar; 运行测试用例。 ValidCollection public @interface ValidCollection { Class<?> elementType
  • 如何结合验证两个或多个字段?(How can I validate two or more fields in combination?)
    问题 我正在使用JPA 2.0 /休眠验证来验证我的模型。 我现在遇到一种情况,必须验证两个字段的组合: public class MyModel { public Integer getValue1() { //... } public String getValue2() { //... } } 如果getValue1()和getValue2()均为null ,则该模型无效,否则有效。 如何使用JPA 2.0 / Hibernate执行这种验证? 使用简单的@NotNull批注,两个getter必须为非null才能通过验证。 回答1 对于多属性验证,应使用类级别的约束。 摘自Bean Validation Sneak Peek第二部分:自定义约束: 类级别的约束你们中有些人对应用跨越多个属性的约束或表达依赖于多个属性的约束的能力表示担忧。 典型的例子是地址验证。 地址具有复杂的规则: 街道名称在某种程度上是标准名称,并且一定要有长度限制邮政编码结构完全取决于国家/地区该城市通常可以与邮政编码相关联,并且可以进行一些错误检查(假设可以使用验证服务) 由于这些相互依存关系,一个简单的属性级别约束确实可以满足要求 Bean验证规范提供的解决方案有两个方面: 它提供了通过使用组和组序列来强制在另一组约束之前应用一组约束的功能。
  • 如何使用休眠将数字字符串验证为数字?(How to validate number string as digit with hibernate?)
    问题 对于 Hibernate 验证,我必须使用哪些注释来验证字符串以应用于以下内容: //should always have trimmed length = 6, only digits, only positive number @NotEmpty @Size(min = 6, max = 6) public String getNumber { return number.trim(); } 如何应用数字验证? 我会在这里只使用@Digits(fraction = 0, integer = 6)吗? 回答1 您可以用单个@Pattern(regexp="[\\d]{6}")替换所有约束。 这意味着一个长度为 6 的字符串,其中每个字符都是一个数字。 回答2 您还可以创建自己的休眠验证注释。 在下面的示例中,我创建了一个名为EnsureNumber的验证注释。 带有此注解的字段将使用EnsureNumberValidator类的isValid方法进行验证。 @Constraint(validatedBy = EnsureNumberValidator.class) @Target({ ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface EnsureNumber { String
  • java bean 属性验证框架 valid
    项目介绍 java 开发中,参数校验是非常常见的需求。 但是 hibernate-validator 在使用过程中,依然会存在一些问题。 特性 支持 fluent-validation 支持 jsr-303 注解 支持 i18n 支持用户自定义策略 支持用户自定义注解 开源地址 valid 创作目的 hibernate-validator 无法满足的场景 如今 java 最流行的 hibernate-validator 框架,但是有些场景是无法满足的。 比如: 验证新密码和确认密码是否相同。(同一对象下的不同属性之间关系) 当一个属性值满足某个条件时,才进行其他值的参数校验。 多个属性值,至少有一个不能为 null 其实,在对于多个字段的关联关系处理时,hibernate-validator 就会比较弱。 本项目结合原有的优点,进行这一点的功能强化。 validation-api 过于复杂 validation-api 提供了丰富的特性定义,也同时带来了一个问题。 实现起来,特别复杂。 然而我们实际使用中,常常不需要这么复杂的实现。 valid-api 提供了一套简化很多的 api,便于用户自行实现。 自定义缺乏灵活性 hibernate-validator 在使用中,自定义约束实现是基于注解的,针对单个属性校验不够灵活。 本项目中,将属性校验约束和注解约束区分开,便于复用和拓展。
  • java bean 属性验证框架 valid
    项目介绍 java 开发中,参数校验是非常常见的需求。 但是 hibernate-validator 在使用过程中,依然会存在一些问题。 特性 支持 fluent-validation 支持 jsr-303 注解 支持 i18n 支持用户自定义策略 支持用户自定义注解 开源地址 valid 创作目的 hibernate-validator 无法满足的场景 如今 java 最流行的 hibernate-validator 框架,但是有些场景是无法满足的。 比如: 验证新密码和确认密码是否相同。(同一对象下的不同属性之间关系) 当一个属性值满足某个条件时,才进行其他值的参数校验。 多个属性值,至少有一个不能为 null 其实,在对于多个字段的关联关系处理时,hibernate-validator 就会比较弱。 本项目结合原有的优点,进行这一点的功能强化。 validation-api 过于复杂 validation-api 提供了丰富的特性定义,也同时带来了一个问题。 实现起来,特别复杂。 然而我们实际使用中,常常不需要这么复杂的实现。 valid-api 提供了一套简化很多的 api,便于用户自行实现。 自定义缺乏灵活性 hibernate-validator 在使用中,自定义约束实现是基于注解的,针对单个属性校验不够灵活。 本项目中,将属性校验约束和注解约束区分开,便于复用和拓展。
  • 错误:找不到类型为java.time.LocalDate的验证器(error: No validator could be found for type: java.time.LocalDate)
    问题 我正在一个使用bean验证(Hibernate Validator 5.1.3.Final)的项目上。 我的bean具有带有@Past批注的属性。 @Past(message = "A data deve estar no passado.") private LocalDate dataAbertura; 但是,当验证发生时,我得到以下异常: 21:46:12,424 ERROR [io.undertow.request] (default task-35) UT005023: Exception handling request to /financeiro/clientes/pessoafisica: javax.servlet.ServletException: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.time.LocalDate. at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:127) [vraptor-4.1.4.jar:] at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter
  • JSR-303依赖项注入和Hibernate(JSR-303 dependency injection and Hibernate)
    问题 Spring 3.0.2,Hibernate 3.5.0,Hibernate-Validator 4.0.2.GA 我正在尝试使用以下方法将Spring依赖项注入ConstraintValidator中: @PersistenceContext private EntityManager entityManager; 我已经使用以下方式配置了应用程序上下文: <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> 根据Spring文档,它应该允许“自定义ConstraintValidators像其他任何Spring bean一样受益于依赖项注入” 在调试器中,我可以看到Spring调用getBean创建ConstraintValidator。 稍后,当刷新触发preInsert时,将创建并调用另一个ConstraintValidator。 问题在于此新ConstraintValidator中的EntityManager为null。 我尝试在ConstraintValidator中注入其他依赖项,这些依赖项始终为null。 有谁知道是否可以将依赖项注入ConstraintValidator中? 回答1
  • 检查休眠映射类中的不变量(Check invariants in hibernate mapped classes)
    问题 使用 hibernate 的一个挑战是托管类必须有一个默认构造函数。 问题是没有明确的点在哪里初始化类并且可以检查不变量。 如果一个类具有依赖于多个属性的不变量,则类设计会变得复杂。 让我们从假设的绿地设计开始: public class A { private int x; private int y; public A(int x, int y) { this.x = x; this.y = y; checkInvariants(this.x, this.y); } private void checkInvariants(int x, int y) { if (x + y « 0) throw new IllegalArgumentException(); } } 这是不满足休眠要求的基本实现。 在构造函数中检查不变量。 (checkInvariants() 方法的内容无关紧要,只是为了说明类不变量可以依赖于多个属性。) 该类可以按如下方式使用: new A(0, 0); new A(-1, 0); //invalid 要满足休眠要求,一种解决方法是添加私有默认构造函数并使用字段访问。 (我省略了休眠映射。) public class H { int x; int y; public H(int x, int y) { this.x = x; this.y = y
  • JSR303自定义验证器被调用两次(JSR303 custom validators being called twice)
    问题 我正在使用Spring MVC创建一个网站,并且为了持久性,我将Spring Data JPA与Hibernate 4作为我的JPA提供程序一起使用。 目前正在使用Hibernate Validator处理验证。 我有一个问题,我的验证程序被两次调用,我不知道为什么。 这是一个问题的主要原因是因为在第二轮中,依存关系没有自动装配到验证器中,并且我收到了空指针异常。 以下是导致失败的调用顺序: 提交注册表单,然后首先调用NotDefaultSectValidator并成功完成用户对象上的“ whereDidYouHearAboutUs”字段。 接下来将调用UniqueUsernameValidator,并成功完成“用户名”字段验证。 控制器上的“ addUserFromForm”方法启动,并且在bindingResults对象中未发现任何错误。 然后在UserService类上调用'addUser'方法。 此方法到达“ userRepository.save(user);”行。 但是永远不要在那之后立即运行'print.ln'行。 跨过此行将回到“ NotDefaultSectValidator”断点。 这是第二次完成,我将再次输入第二个验证器“ UniqueUsernameValidator”。 在这里,我得到了一个空指针异常,因为由于某种原因
  • 使用Spring的JSR-303约束验证器中的依赖项注入失败(Dependency Injection in JSR-303 Constraint Validator with Spring fails)
    问题 我在这里和这里都遇到了同样的问题,但是找不到解决方案。 因此,我的示例测试项目将显示整个相关配置和代码: 约束注释: @Target({ ElementType.METHOD, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = FooValidator.class) public @interface FooValid { String message(); Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } 带注释的PoJo: public class Foo { @FooValid(message = "Test failed") private Integer test; [...] } 带@Validated的带注释的服务: @Service @Validated public class FooService { private final Test test; @Autowired public FooService(final Test test) { this.test = test; } public void foo(@Valid
  • JSF/Hibernate NotBlank 验证(JSF/Hibernate NotBlank validation)
    问题 我有一个简单的 JSF+RichFaces 表单,其中包含一些字段,显然还有一个支持 bean 来存储它们。 在那个 bean 中,所有必要的属性都有验证注释(jsr303/hibernate),但我似乎找不到可以检查属性(字符串)是否为空的注释。 我知道 spring 模块中有一个 @NotBlank 注释,但 JSF 不支持 spring 验证。 有什么简单的方法可以检查它还是应该编写自己的注释? @Edit:我已经尝试过 jsr303 和 hibernate 中的 @NotNull 和 @NotEmpty,但它们都失败了,我仍然可以发送像“”这样的空白字符串。 回答1 如果您使用 Hibernate Validator 4.1 作为您的 JSR-303 实现,它们会提供一个 @NotBlank 注释,该注释完全符合您的要求,与 @NotNull 和 @NotEmpty 分开。 您需要使用(当前)最新版本,但这会起作用。 如果你因为某些原因不能去到最新版本,自己写一个注解也不需要太多。 回答2 Hibernate Validator 4.1+ 提供了一个自定义的仅字符串 @NotBlank 注释,它在修剪空白后检查非空和非空。 @NotBlank的 api 文档指出: NotEmpty 的不同之处在于尾随空格被忽略。 如果不清楚
  • Autowired在“自定义约束”验证器中给出Null值(Autowired gives Null value in Custom Constraint validator)
    问题 我对Spring完全陌生,因此已经针对所提出的问题寻找了一些关于SO的答案。 这里是链接: Spring 3.1自动装配在自定义约束验证器中不起作用 将服务自动装配到验证器中 在自定义约束验证器中,自动装配的存储库为空 我有一个Spring项目,我想在其中使用Hibernate Validator进行对象验证。 根据我在网上阅读的内容和一些论坛,我尝试注入验证器,如下所示: @Bean public Validator validator() { return new LocalValidatorFactoryBean().getValidator(); } 但是无论我在哪里使用 @Autowired Validator validator; 它采用了Spring的验证器实现,而不是Hibernate的验证器。 我不知道如何准确地注入Hibernate验证程序,并简单地将其自动连接到其他类上,所以我使用了便宜的技巧,现在我的Java Config看起来像这样 @Bean public Validator validator() { // ValidatorImpl is Hibernate's implementation of the Validator return new ValidatorImpl(); }
  • 休眠-hibernate.hbm2ddl.auto =验证(Hibernate - hibernate.hbm2ddl.auto = validate)
    问题 我对hibernate.hbm2ddl.auto = validate的实际工作方式很感兴趣,并且正在努力寻找全面的文档。 我们最近发现生产系统受到http://opensource.atlassian.com/projects/hibernate/browse/HHH-3532的影响(Hibernate在名称上匹配外键,而不是签名,因此将为您重新创建外键)并进入休眠状态.hbm2ddl.auto = update已从我们的下一个版本中删除。 我很高兴能完全摆脱hibernate.hbm2ddl.auto并自己管理我们的数据库。 但是,并非我的所有同事都拥有这种世界观,有些人热衷于重新添加hibernate.hbm2ddl.auto = validate。 我担心这会遇到相同的问题,并且我有兴趣查找有关此验证实际工作方式的更多文档。 Hibernate社区文档(http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html)实际上只是引用了这些值。 有没有人有任何好的文档说明,或者在生产系统中使用validate的任何现实生活经验? 回答1 我担心这会遇到相同的问题,并且我有兴趣查找有关此验证实际工作方式的更多文档。 我认为,最好的文档是源代码
  • JSR 303 bean验证,扩展的ConstraintValidator无法使用CDI(The JSR 303 bean validation, The extended ConstraintValidator cannot use the CDI)
    问题 我尝试在类级别学习具有bean验证的JSF 2.0,如下所示:- 实用程序 @Singleton public class MyUtility { public boolean isValid(final String input) { return (input != null) || (!input.trim().equals("")); } } 约束注释 @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.FIELD }) @Constraint(validatedBy = Validator.class) @Documented public @interface Validatable { String message() default "Validation is failure"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } 约束验证器 public class Validator extends ConstraintValidator<Validatable, MyBean> { /
  • 是否有可用的JSR-303(bean验证)实现?(Is there an implementation of JSR-303 (bean validation) available?)
    问题 我知道有非标准框架,例如commons-validator和hibernate Validator。 我想知道是否有人知道官方标准的实施。 回答1 Hibernate Validator是JSR-303的参考实现 回答2 现在有2种兼容的实现: Apache Bean验证(以前为agimatec) 休眠验证器 您可以在此处访问两者的基准和简要说明:http://carinae.net/2010/06/benchmarking-hibernate-validator-and-apache-beanvalidation-the-two-jsr-303-implementations/ 回答3 实现方式: 敏捷验证休眠验证器 回答4 OVaL不是JSR-303验证器,但是它可以将jsr303约束转换为自己的约束。 回答5 我认为Spring Framework从版本3开始成为JSR303兼容。 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#validation-beanvalidation 就设置支持而言,Spring Framework 4.0支持Bean验证1.0(JSR-303)和Bean验证1.1(JSR-349)
  • Hibernate Validator 异常“找不到类型为 java.lang.String 的验证器。”(Hibernate Validator exception “No validator could be found for type: java.lang.String.”)
    问题 我使用 Spring 和 Spring MVC 3.1、Hibernate 3、Hibernate Validator 4.3。 我想添加我的自定义约束验证器,但似乎我的验证器没有被调用并且总是得到“找不到类型的验证器”异常。 我做错了什么吗? 我总是遇到这个异常的大问题 javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.lang.String. at org.hibernate.validator.internal.engine.ConstraintTree.verifyResolveWasUnique(ConstraintTree.java:394) at org.hibernate.validator.internal.engine.ConstraintTree.findMatchingValidatorClass(ConstraintTree.java:375) 但是如果我删除我的自定义约束验证器,一切正常。 这是我的代码,您能帮我找到导致此异常的来源吗? test.constraint.ActorConstraint @Target({ElementType.METHOD, ElementType.FIELD
  • Cross field validation with Hibernate Validator (JSR 303)(Cross field validation with Hibernate Validator (JSR 303))
    问题 Hibernate Validator 4.x中是否有跨域验证的实现(或第三方实现)? 如果没有,实现跨域验证器的最干净方法是什么? 例如,如何使用API​​来验证两个bean属性是否相等(例如,验证密码字段与密码验证字段匹配)。 在注解中,我期望这样的东西: public class MyBean { @Size(min=6, max=50) private String pass; @Equals(property="pass") private String passVerify; } 回答1 每个字段约束都应由不同的验证者注释处理,换句话说,不建议对一个字段进行其他字段的验证注释检查。 跨领域验证应在课程级别进行。 另外,JSR-303第2.2节表示同一类型的多个验证的首选方法是通过注释列表。 这样可以在每次匹配中指定错误消息。 例如,验证通用形式: @FieldMatch.List({ @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match"), @FieldMatch(first = "email", second = "confirmEmail", message = "The email fields must
  • 如何自定义 Hibernate @Size 错误消息以指示输入字段的长度(How to customize Hibernate @Size error message to indicate length of entered field)
    问题 我想自定义文本字段的错误消息以包含输入的实际字符数。 我已经能够让它工作,但对我的解决方案不满意,所以我想知道其他人做了什么来实现这一点。 春天 4.1.2 休眠 4.3.10 休眠验证器 5.1.3 字段注释(仅限 10 个用于测试目的 - 实际大小为 150 个) @Column(name = "NAME", nullable = false) @Size(max=10) private String name; 消息属性 Size.person.name=Maximum is {1} characters JSP代码 <spring:bind path="person.name"> <c:set var="nameError">${status.errorMessage}</c:set> <c:set var="nameDisplayValue">${status.displayValue}</c:set> <c:set var="nameCode">${status.errorCode}</c:set> </spring:bind> <c:if test="${fn:contains(nameCode,'Size')}"> <c:set var="nameLen">${fn:length(nameDisplayValue)}</c:set> <c:if test="$
  • Spring Boot2 系列教程 (十五) | 服务端参数校验之一
    估计很多朋友都认为参数校验是客户端的职责,不关服务端的事。其实这是错误的,学过 Web 安全的都知道,客户端的验证只是第一道关卡。它的参数验证并不是安全的,一旦被有心人抓到可乘之机,他就可以有各种方法来摸拟系统的 Http 请求,访问数据库的关键数据。轻则导致服务器宕机,重则泄露数据。所以,这时就需要设置第二道关卡,服务端验证了。老项目的服务端校验@RestController @RequestMapping("/student") public class ValidateOneController { @GetMapping("/id") public Student findStudentById(Integer id){ if(id == null){ logger.error("id 不能为空!"); throw new NullPointerException("id 不能为空"); } return studentService.findStudentById(id); } }看以上代码,就一个的校验就如此麻烦。那我们是否有好的统一校验方法呢?鉴于 SpringBoot 无所不能。答案当然是有的。其中,Bean Validator 和 Hibernate Validator 就是两套用于验证的框架,二者都遵循 JSR-303 ,可以混着用,鉴于二者的某些
  • 在保留实体之前检查约束是否违反(checks for constraint violation before persisting an entity)
    问题 什么是防止在创建约束约束之前进行检查的最佳机制? 实体的修改? 假设“用户”实体具有“ loginid”作为唯一约束,明智的做法是在创建或修改之前检查是否已经存在具有该loginid名称的用户条目。 或者 您是否要让数据库抛出ConstraintViolationException并在UI层中适当地处理此消息。 在jboss接缝框架中应在哪里执行此类检查。 注意:目前,没有对seam-gen代码强制执行此类检查。 当前,我们将Seam 2.2,Richfaces与Hibernate结合使用。 回答1 即使您在保留用户对象之前检查代码中的条件,也始终有机会在检查时间和保留新用户之间有人创建重复的登录ID。 但是,如果您进行显式检查,则在UI中显示适当的错误消息会更加容易。 如果您在表上有多个约束,则捕获ConstraintViolationException不会使您轻松确定违反了哪个约束。 所以我会两者都做。 假设您是从Seam的EntityHome扩展而来的: 在persist()方法中,运行查询以确保loginid是唯一的。 如果不是,则将错误消息添加到适当的控件中,并返回null。 包装对super.persist()的调用并捕获ConstraintViolationException,显示通用的重复错误消息 编辑 正如Shervin提到的那样