代码之家  ›  专栏  ›  技术社区  ›  Robert Munteanu

将自定义ResourceBundle与Hibernate验证程序一起使用

  •  12
  • Robert Munteanu  · 技术社区  · 13 年前

    我正在尝试为Hibernate验证程序4.1到Spring3.0设置自定义消息源。我已经设置了必要的配置:

    <!-- JSR-303 -->
    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="validationMessageSource" ref="messageSource"/>
     </bean>
    

    翻译是从我的消息源提供的,但似乎在消息源中查找了消息本身中的替换标记,即:

    my.message=the property {prop} is invalid
    

    有调用可在messagesource中查找“prop”。进入 ResourceBundleMessageInterpolator.interpolateMessage 我注意到JavaDoc声明:

    根据JSR 303中指定的算法运行消息插值。

    注: 用户包中的查找是递归的,而默认包中的查找不是递归的!

    在我看来,对于用户指定的包,递归总是会发生,因此实际上,我不能转换像大小那样的标准消息。

    如何插入自己的消息源并能够在消息中替换参数?

    1 回复  |  直到 12 年前
        1
  •  18
  •   Community Egal    7 年前

    在我看来,这就像递归 总是发生在 用户指定的包,因此实际上 无法翻译标准邮件 就尺寸而言。

    休眠验证器的ResourceBundleMessageInterpolator创建两个ResourceBundleLocator实例(即PlatformResourceBundleLocator),一个用于用户定义的验证消息-UserResourceBundleLocator,另一个用于JSR-303标准验证消息-DefaultResourceBundleLocator。

    出现在两个大括号内的任何文本,例如 {someText} 在消息中被视为replacementtoken。ResourceBundleMessageInterpolator尝试查找可替换ResourceBundleLocator中的ReplacementToken的匹配值。

    1. 首先在userdefinedvalidationmessages(递归)中,
    2. 然后在defaultvalidationmessages中(这不是递归的)。

    所以,如果在定制资源包中放置一个标准的JSR-303消息,那么说, validation_erros.properties ,它将被您的自定义消息替换。看看这个 EXAMPLE 标准的NotNull验证消息“may not be null”已被自定义的“MyNotNullMessage”消息替换。

    如何插入我自己的消息 源并能够有参数 在消息中被替换?
    my.message=属性属性 无效

    在浏览完两个resourcebundlelocator之后,resourcebundlemessageinterpolator会在resolvedmessage(由两个bundle解析)中找到更多replacetoken。这些替换令牌只是 批注属性的名称 ,如果在resolvedMessage中找到此类replaceToken,则它们将替换为 匹配注释属性的值 .

    resourcebundlemessageinterpolator.java[行168,4.1.0.最终]

    resolvedMessage = replaceAnnotationAttributes( resolvedMessage, annotationParameters );
    

    提供一个用自定义值替换属性的例子,我希望它能帮助您……

    mynot空.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;
        }
    }
    

    用户.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;
        }
    }
    

    验证\错误.属性

    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