Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate验证程序中的消息表达式出现问题_Java_Expression_Message_Bean Validation_Hibernate Validator - Fatal编程技术网

Java hibernate验证程序中的消息表达式出现问题

Java hibernate验证程序中的消息表达式出现问题,java,expression,message,bean-validation,hibernate-validator,Java,Expression,Message,Bean Validation,Hibernate Validator,我正在做一个项目,我已经使用Hibernate验证器一段时间了。 最近我尝试在我的验证消息中使用EL特性,但我得到了不一致的结果(据我所知) 根据有关消息插值步骤的文档,在计算消息表达式(包含在“{..}”中的参数)之前解析消息参数(包含在“${..}”中的参数)。因此,我得出结论,可以写这样的信息: ${validatedValue > someValue ? '{x.y.z.message}' : '{x.y.w.message}'} 并期望结果是键为x.y.z.messag

我正在做一个项目,我已经使用Hibernate验证器一段时间了。 最近我尝试在我的验证消息中使用EL特性,但我得到了不一致的结果(据我所知)

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

    ${validatedValue > someValue ? '{x.y.z.message}' : '{x.y.w.message}'}
并期望结果是键为
x.y.z.message
x.y.w.message
的消息文本,其中
x.y.z.message
x.y.w.message
被假定为正确引导的资源包中有效且已定义的消息键

为了澄清问题,我使用TestNG编写了一个测试用例,并对hibernate-validator-5.0.1.Finalhibernate-validator-5.1.0-Alpha运行了它。正如测试评论中所指出的,这些版本所获得的结果在这个特定问题上各不相同,这提示我有一个实现错误。我起初认为这可能与你有关,但似乎更深一层

以下是测试用例:

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)");
    }
}
import java.util.Set;
导入javax.validation.ConstraintViolation;
导入javax.validation.Validator;
导入javax.validation.constraints.Size;
导入org.testng.annotations.Test;
导入静态org.testng.Assert.assertEquals;
公共类HibernateValidationTest
{
公共类实体
{
公共服务指数;
@大小(最小值=4,最大值=10,消息=“${validatedValue.length()
在本测试中,
Entity.getMessage3()
演示了测试最后一部分捕获的问题。根据我的理解,此消息必须是
大小必须介于4和10之间(Error msg.#3)
,但它是
大小必须介于4和10之间(${validatedValue.length()
在版本5.0.1上,并且
{javax.validation.constraints.Size.message}(${validatedValue.length()
5.1.0.Alpha上

任何人都可以对这一点进行评估,提出问题,或者帮助我发现自己的错误


谢谢您的时间。

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

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


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

在讨论了这一点之后,我决定遵循@Gunnar建议,因为我们使用OSGi,我成功地完成了一个快速绑定类路径技巧,将修改后的
ResourceBundleMessageInterpolator
放置在HV自动选择的原始绑定器之前。

谢谢,我将等待对此的一些提示。与此同时,我花时间在hibernate源代码中跟踪这一点,并找到了私有正则表达式模式常量
ResourceBundleMessageInterpolator。MESSAGE_PARAMETER_pattern
是在
ResourceBundleMessageInterpolator.interpolateMessage中使用时导致问题的模式