当前位置: 首页 > 知识库问答 >
问题:

hibernate验证器中消息表达式的问题

赵高韵
2023-03-14

根据有关消息插值步骤的文档,消息参数(包含在“{..}”中的参数)在计算消息表达式(包含在“${..}”中的参数)之前被解析。因此,我得出结论,允许写这样的消息:

    ${validatedValue > someValue ? '{x.y.z.message}' : '{x.y.w.message}'}

并且期望其键为X.Y.Z.messageX.Y.W.message的消息文本为结果,其中X.Y.Z.messageX.Y.W.message被假定为有效的消息键,并且在正确引导的资源束中已经定义了消息键。

为了澄清问题,我使用TestNG编写了一个测试用例,并在hibernate-validator-5.0.1.final和hibernate-validator-5.1.0-alpha上运行它。正如在测试注释中所指出的,这些版本所获得的结果在这个特定的问题上各不相同,这暗示了我一个实现错误。我最初认为这可能与[HV-798]有关,但它似乎更深。

下面是测试用例:

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.constraints.Size;

import org.testng.annotations.Test;

import static org.testng.Assert.assertEquals;

public class HibernateValidationTest
{
    public class Entity
    {
        public int  caseIndex;

        @Size(min = 4, max = 10, message = "${validatedValue.length() < min ? 'Error msg.#1' : 'Error msg.#2'}")
        public String getMessage1()
        {
            if (caseIndex == 0)
                return "abc";
            return "abcd";
        }

        @Size(min = 4, max = 10, message = "{javax.validation.constraints.Size.message}")
        public String getMessage2()
        {
            if (caseIndex == 1)
                return "abc";
            return "abcd";
        }

        @Size(min = 4, max = 10, message = "{javax.validation.constraints.Size.message} (${validatedValue.length() < min ? 'Error msg.#3' : '{javax.validation.constraints.Size.message}'})")
        public String getMessage3()
        {
            if (caseIndex == 2)
                return "abc";
            return "abcd";
        }
    }

    @Test
    public void testValidatorBug()
    {
        Validator validator = javax.validation.Validation.buildDefaultValidatorFactory().getValidator();
        Set<ConstraintViolation<Entity>> violations;
        ConstraintViolation<Entity> violation;
        Entity entity = new Entity();

        /**
         * PASS
         */
        entity.caseIndex = 0;
        violations = validator.validate(entity);
        assertEquals(violations.size(), 1);
        violation = violations.iterator().next();
        assertEquals(violation.getMessage(), "Error msg.#1");

        /**
         * PASS
         */
        entity.caseIndex = 1;
        violations = validator.validate(entity);
        assertEquals(violations.size(), 1);
        violation = violations.iterator().next();
        assertEquals(violation.getMessage(), "size must be between 4 and 10");

        /**
         * FAIL
         * 
         * Violation message:
         * 
         * - on version hibernate-validator-5.0.1.Final: 
         *  size must be between 4 and 10 (${validatedValue.length() < min ? 'Error msg.#3' : '{javax.validation.constraints.Size.message}'})
         * 
         * - on hibernate-validator-5.1.0-20131114.015215-37: 
         *  {javax.validation.constraints.Size.message} (${validatedValue.length() < min ? 'Error msg.#3' : '{javax.validation.constraints.Size.message}'})
         */
        entity.caseIndex = 2;
        violations = validator.validate(entity);
        assertEquals(violations.size(), 1);
        violation = violations.iterator().next();
        assertEquals(violation.getMessage(), "size must be between 4 and 10 (Error msg.#3)");
    }
}

在此测试中,Entity.getMessage3()演示了测试最后一部分所捕获的问题。根据我的理解,此消息必须是大小必须介于4和10之间(Error msg.#3),但在5.0.1版本上是大小必须介于4和10之间(${validatedvalue.lengts() ,而在5.1.0.alpha版本上是 {javax.validation.constraints.size.message}(${validatedvalue.lengts()

有谁能好心的评价一下这个问题,或者帮我找出我自己的错误。

谢谢你抽出时间。


共有1个答案

徐知
2023-03-14

这似乎与EL表达式内的消息参数嵌套有关。

阅读规范的措辞,我看不出有什么理由不允许这样做,但我不确定我们是否有意支持这种情况(我想我们在这种情况下提供了一个示例)。我已经转发了这个问题,看看BV EG上的其他人是怎么想的。

Hibernate Validator当前检测到这种嵌套,并在这种情况下引发异常。这就是插值消息保持不变的原因(这是规范要求的)。

 类似资料:
  • 我试图覆盖默认的Hibernate验证器消息,但没有成功。我已经为几个文本使用了一个资源包,它工作得很好。问题在于验证器的消息。 详细内容: 我创建了以下文件:ValidationMessages\u de.properties并将其放置在\src\main\resources\translations\ValidationMessages\u de.properties下。该文件具有以下资源:o

  • 我有一个测试类,在那里我测试一个用@NotNull注释的域模型 在这个资源包中,支持相当多的语言(英语、德语、法语……) 例 @NOTNULL违反德语消息 当我在测试时,我如何强制Hibernate验证器为来自资源包的冲突消息选择特定的语言?现在,我收到英文违规信息。然而,在另一个机器德国。

  • 问题内容: 给定一个用户输入字符串,如何确定它在Java中是否为有效的Xpath表达式。很好奇,因为我找不到使用javax.xml.xpath库的方法。谢谢。 问题答案: 我假设您要验证语法,但是如果表达式在xml或xml架构的上下文中有效,则不要验证。您可以使用compile(..)方法,如果xpath的语法不正确,它将引发异常。

  • 用户将输入一些公式/表达式。 我想检查作为函数字符串输入的公式/表达式是否正确(根据MVEL标准)。 下面是一个有效的表达式, 以下是不正确的表达, 下面是代码片段, MVEL提供的API是否接受表达式String并在表达式不正确时返回布尔/抛出异常?

  • 我无法使用Spring MVC 4.2.5版本来处理hibernate validation 5.1.0.Final。 我的WebConfig: 我有一个ExceptionHanlder,它获取验证消息,并将其作为JSON推回: 在controller中,我使用@org.springframework.validation.annotation.validated。 PS2.我确信我的messag

  • 我正在使用石英调度程序来安排我的工作。我有一个错误的cron表达式: 当我这样做的时候: is。但是当我查看表达式时,它显然是错误的。其他人也面临类似的问题吗? 注:包装为:包装组织。石英 石英的版本是:2.2.3 请检查来自的CronExpression类http://www.javadoc.io/doc/org.quartz-scheduler/quartz/2.2.3 我还尝试了类的方法,但