Java hibernate验证程序中的消息表达式出现问题
我正在做一个项目,我已经使用Hibernate验证器一段时间了。 最近我尝试在我的验证消息中使用EL特性,但我得到了不一致的结果(据我所知) 根据有关消息插值步骤的文档,在计算消息表达式(包含在“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
{..}
”中的参数)之前解析消息参数(包含在“${..}
”中的参数)。因此,我得出结论,可以写这样的信息:
${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.Final和hibernate-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中使用时导致问题的模式