如何使Hibernate Validator在第一次违反字段时停止验证? - java

我有一个bean,我在其中为每个字段定义多个验证注释,例如

@NotEmpty
@Pattern(regexp="(\\-?\\d)+")
@Min(value=1)
String myField;

我遇到了两个无法以任何简单方式解决的问题。

  • 每个字段的指定注释的验证顺序是随机的,即不会按照定义注释的顺序发生。我相信@GroupSequence将无济于事,因为它仅定义组验证序列,而不是注释序列。
    正如@Tom正确注释的那样,违规被报告为Set,这意味着注释的执行顺序与所报告的违规之间没有1:1的映射。
  • 我想使每个字段仅使一个规则无效,即,如果它与模式不匹配,请不要尝试检查该值是否> =1。当前,如果将myField设置为“abc”,它将报告@Pattern和@Min违规。将验证器的failFast属性设置为true并没有帮助,因为我使用相同的验证器实例来验证bean中的所有字段,并且在遇到整个bean的第一次违规时,它将停止验证其他字段。
  • 编辑。我尝试使用@ReportAsSingleViolation实现自定义复合约束。问题在于,它将为撰写中涉及的所有违规报告相同的消息。这不是我所需要的。

    建议,好吗?

    参考方案

    应该可以结合使用validation groups和完全定义的validation group sequence来创建想要实现的行为

    从JSR-349 (aka. BeanValidation 1.1) spec, paragraph 4.4.2报价

    处理组在第4.6节中定义;如果序列中处理的组之一产生一个或多个约束违例,则序列之后的组必须不被处理。 这可确保仅在另一组约束有效时才评估一组约束。
    由我突出

    这应该是相对容易的,通过Group Sequence Example

    @GroupSequence({YourClass.class, Second.class, Third.class})
    public class YourClass {
        @NotNull
        @Pattern(regexp="(\\-?\\d)+", groups=Second.class)
        @Min(value=1, groups=Third.class)
        String myField;
    }
    

    SecondThird定义为简单的标记接口应该可以解决问题。请注意,这不会验证所有字段,直到第一个约束违反,而是直到第一个总体违反。

    这意味着您的某些字段在解决其他字段的违规问题后可能会变得无效。

    如果所有其他方法都失败了,您仍然可以重新实现行为组件,即验证提供程序。
    您应该能够使用validation.xml提供自己的 ConstraintValidatorContext 实现。

    请注意,您会拥有来违反 ConstraintValidatorContext.ConstraintViolationBuilder 的合同:

    要创建ConstraintViolation,必须调用以下任一方法
    在以下接口之一中可用的addConstraintViolation()方法
    流利的API。

    如果在addConstraintViolation()之后打开另一个方法称为
    ConstraintViolationBuilder或其任何关联对象
    IllegalStateException被引发。

    Hibernate:现实世界中的模式导出? - java

    我很好奇我的下一个项目完全使用架构导出。我认为这是真正处理对象而非基础数据库的非常有用的方法。只需创建并注释模型,然后将其导出即可。但是从先创建表然后创建模型对象的习惯来看,我对完全使用模式导出有疑问。这主要是因为我真的很深入休眠。但是我仍然好奇使用模式导出时,该区域列表是否会成为问题。请分享您的经验..表之间的关系代理/复合主键支持当我只想从多个模型中导出…

    Java:线程池如何将线程映射到可运行对象 - java

    试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

    JAVA:字节码和二进制有什么区别? - java

    java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

    java:继承 - java

    有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

    Java:BigInteger,如何通过OutputStream编写它 - java

    我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…