2017-08-14 285 views
0

我想为LocalValidatorFactoryBean使用Spring的ReloadableResourceBundleMessageSource,这样当我更新错误消息时,它应该反映而不需要重新启动服务器。我使用Spring 4.1.4,hibernate-validator 4.3.2.Final。 下面是代码的细节 -org.hibernate.validator.constraints不挑选重新加载的消息

的context.xml -

<mvc:annotation-driven validator="validator" /> 
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
     <property name="basenames"> 
     <list> 
      <value>file:../conf/fileapplication</value> <!-- Messages here will override the below properties file--> 
      <value>/WEB-INF/application</value> 
     </list> 
    </property> 
    <property name="cacheSeconds" value="10"></property> <!-- Will check for refresh every 10 seconds --> 
</bean> 
<bean name="validator" 
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
    <property name="validationMessageSource"> 
     <ref bean="messageSource"/> 
    </property> 
</bean> 

模型 -

import org.hibernate.validator.constraints.NotBlank; 
public class InputForm { 

@NotBlank (message = "{required.string.blank}") 
String requiredString; 

控制器 -

@RequestMapping(value = "/check/string", method = RequestMethod.POST) 
public String checkString(
     @ModelAttribute("formModel") @Valid InputForm inputForm , 
     BindingResult result, Model model, HttpServletResponse response, 
     HttpServletRequest request) { 
     if (result.hasErrors()) { 
     model.addAttribute("formModel", inputForm); 
     return "userInput"; 
     } 
     // Do some backend validation with String 
     result.reject("string.not.valid", 
       "String is Invalid"); 
     model.addAttribute("formModel", inputForm); 
     return "userInput"; 
} 

application.properties(在/ WEB_INF /文件夹)

required.string.blank=Please enter the required string. 
string.not.valid=Please enter a valid string. 

fileapplication.properties(in/conf/folder。将覆盖上面的文件)

required.string.blank=You did not enter the required string. #Does not reflect when I change here 
string.not.valid=You did not enter a valid string. #Reflects when I change here 

现在我面临的问题是,当我在它反映了在运行时fileapplication.properties更新“string.not.valid”,我看到了更新的消息。但是,当我更新fileapplication.properties中的“required.string.blank”时,它不会在运行时反映出来。 请注意,应用程序启动时,覆盖部分对于这两个消息都正常工作。但“重新加载”部分对于“required.string.blank”无法正常工作。

回答

0

这就是我基于我的研究所得出的结论 - 我们需要创建自己的MessageInterpolator,并将其作为依赖项添加到验证器而不是消息源。因为当我们添加一个messageSource作为依赖项时,它将被验证器默认缓存,并且任何重新加载spring的消息都不会在验证器的messageSource的缓存实例中生效。

以下是详细信息:

在context.xml中,添加自定义MessageInterpolator作为依赖于LocalValidatorFactoryBean,而不是为messageSource:

<mvc:annotation-driven validator="validator" /> 
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
    <property name="basenames"> 
    <list> 
     <value>file:../conf/fileapplication</value> <!-- Messages here will override the below properties file--> 
     <value>/WEB-INF/application</value> 
    </list> 
</property> 
<property name="cacheSeconds" value="10"></property> <!-- Will check for refresh every 10 seconds --> 
</bean> 

<bean name="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
    <property name="messageInterpolator"> 
     <ref bean="messageInterpolator"/> 
    </property> 
</bean> 

<bean name="messageInterpolator" 
    class="com.my.org.support.MyCustomResourceBundleMessageInterpolator"> 
    <constructor-arg ref="messageSource" /> 
</bean> 

通过扩展Hibernate的org.hibernate.validator创建自定义MessageInterpolator。 messageinterpolation.ResourceBundleMessageInterpolator。

public class MyCustomResourceBundleMessageInterpolatorextends 
    ResourceBundleMessageInterpolator { 
    public MyCustomResourceBundleMessageInterpolator(MessageSource messageSource) 
    { 
    // Passing false for the second argument 
    // in the super() constructor avoids the messages being cached. 
    super(new MessageSourceResourceBundleLocator(messageSource), false);  
    } 
} 

模型,控制器和属性文件可以与问题中的相同。