我试图通过Spring 3.0为Hibernate Validator 4.1设置自定义消息源。我已经设置了必要的配置:
<!-- JSR-303 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
翻译是从我的消息来源提供的,但似乎在消息来源中查找消息本身中的替换令牌,即:a /:
my.message=the property {prop} is invalid
有电话要求查找&#39; prop&#39;在messageSource中。进入ResourceBundleMessageInterpolator.interpolateMessage
我注意到javadoc声明:
根据JSR 303中指定的算法运行消息插值。
注意: 用户捆绑包中的查找是递归的,而默认捆绑包中的查找不是!
在我看来,对于用户指定的包总是会发生递归,所以实际上我无法翻译像Size这样的标准消息。
如何插入我自己的消息源并能够在消息中替换参数?
答案 0 :(得分:18)
这就像递归一样 将永远发生在一个 用户指定的包,所以实际上我 无法翻译标准消息 就像大小一样。
Hibernate Validator的ResourceBundleMessageInterpolator创建两个ResourceBundleLocator实例(即PlatformResourceBundleLocator),一个用于UserDefined验证消息 - userResourceBundleLocator,另一个用于JSR-303标准验证消息 - defaultResourceBundleLocator。
出现在两个大括号内的任何文字,例如邮件中的{someText}
被视为replacementToken。 ResourceBundleMessageInterpolator尝试查找匹配值,该值可替换ResourceBundleLocators中的replacementToken。
因此,如果您在自定义ResourceBundle中添加标准JSR-303消息validation_erros.properties
,它将被您的自定义消息替换。请参阅此EXAMPLE标准NotNull验证消息'可能不为空'已被自定义'MyNotNullMessage'消息替换。
如何插入我自己的信息 源和能够有参数 在消息中被替换?
my.message =属性{prop}是 无效
在浏览了两个ResourceBundleLocators之后,ResourceBundleMessageInterpolator在resolvedMessage中找到更多的replaceTokens(由两个bundle解析)。这些replacementToken只是Annotation属性的名称,如果在resolvedMessage中找到了这样的replaceTokens,它们将被匹配的Annotation属性的值替换。
ResourceBundleMessageInterpolator.java [第168行,4.1.0.Final]
resolvedMessage = replaceAnnotationAttributes( resolvedMessage, annotationParameters );
提供一个用自定义值替换{prop}的示例,我希望它能帮到你......
<强> MyNotNull.java 强>
@Constraint(validatedBy = {MyNotNullValidator.class})
public @interface MyNotNull {
String propertyName(); //Annotation Attribute Name
String message() default "{myNotNull}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default {};
}
<强> MyNotNullValidator.java 强>
public class MyNotNullValidator implements ConstraintValidator<MyNotNull, Object> {
public void initialize(MyNotNull parameters) {
}
public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
return object != null;
}
}
<强> User.java 强>
class User {
private String userName;
/* whatever name you provide as propertyName will replace {propertyName} in resource bundle */
// Annotation Attribute Value
@MyNotNull(propertyName="userName")
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
<强> validation_errors.properties 强>
notNull={propertyName} cannot be null
<强>测试强>
public void test() {
LocalValidatorFactoryBean factory = applicationContext.getBean("validator", LocalValidatorFactoryBean.class);
Validator validator = factory.getValidator();
User user = new User("James", "Bond");
user.setUserName(null);
Set<ConstraintViolation<User>> violations = validator.validate(user);
for(ConstraintViolation<User> violation : violations) {
System.out.println("Custom Message:- " + violation.getMessage());
}
}
<强>输出强>
Custom Message:- userName cannot be null