2015-08-01 5 views
3

Я использую ReloadableResourceBundleMessageSource для хранения списка значений моей системы. Поэтому я могу использовать функциональность i18Nполучить все ключи от spring ReloadableResourceBundleMessageSource

Я использую несколько ресурсов в basenames ReloadableResourceBundleMessageSource. Я хочу передать всем локализованным ярлыкам веб-интерфейса клиенту (front-end), чтобы он был локально локализован на клиенте. Есть ли способ загрузить все ключи моих пакетов ресурсов?

здесь мое определение ReloadableResourceBundleMessageSource боб:

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
    <property name="basenames"> 
     <list> 
      <value>classpath:resource1</value> 
      <value>classpath:resource2</value> 
     </list> 
    </property> 
    <property name="cacheSeconds" value="60"/> 
    <property name="defaultEncoding" value="UTF-8"/> 
    <property name="useCodeAsDefaultMessage" value="true"/> 
</bean> 

и это мой контроллер, передать все ключи:

@Component 
@RequestMapping("/bundle") 
public class ResourceBundleController { 

    @Autowired 
    private MessageSource messageSource; 

    @RequestMapping(value = "/locales.js") 
    public ModelAndView strings(HttpServletRequest request) { 

     // Call the string.jsp view 
     return new ModelAndView("/WEB-INF/includes/locales.jsp", "keys", ???);// HERE IS MY PROBLEM. HOW SHOULD I GET ALL THE KEYS FROM MESSAGESOURCE 
    } 
} 

и вот мой пакет ресурсов ключи для клиента:

<%@page contentType="text/javascript" pageEncoding="UTF-8"%> 
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%> 

var messages = {}; 

<c:forEach var="key" items="${keys}"> 
    messages["<spring:message text='${key}' javaScriptEscape='true'/>"] = "<spring:message code='${key}' javaScriptEscape='true' />"; 
</c:forEach> 

Любая помощь будет оценена по достоинству.

ответ

5

Обновленной информация о конфигурации яровой касается кэша пакета ресурсов

Вы могли бы сделать что-то вроде этого:

собственной реализации ReloadableResourceBundleMessageSource:

public class ExposedResourceMessageBundleSource extends ReloadableResourceBundleMessageSource { 

    private static final Logger LOGGER = Logger.getLogger(ExposedResourceMessageBundleSource.class); 

    @Override 
    protected Properties loadProperties(Resource resource, String fileName) throws IOException { 

     LOGGER.info("Load " + fileName); 
     return super.loadProperties(resource, fileName); 
    } 

    /** 
    * Gets all messages for presented Locale. 
    * @param locale user request's locale 
    * @return all messages 
    */ 
    public Properties getMessages(Locale locale){ 
     return getMergedProperties(locale).getProperties(); 
    } 
} 

Определения службы для обработки операций reasource :

public interface MessageResolveService extends MessageSourceAware{ 
    String getMessage(String key, Object[] argumentsForKey, Locale locale); 
    Map<String,String> getMessages(Locale locale); 
} 

И реализация:

@Service 
    public class MessageResolverServiceImpl implements MessageResolveService{ 
     private static final Logger LOGGER = Logger.getLogger(MessageResolverServiceImpl.class); 

     private MessageSource messageSource; 

     @Override 
     public void setMessageSource(MessageSource messageSource) { 
      LOGGER.info("Messages i18n injected"); 
      this.messageSource = messageSource; 
     } 

     public String getMessage(String key, Object[] arguments, Locale locale){ 
      String message = ""; 
      try{ 
       message = messageSource.getMessage(key,arguments,locale); 
      } catch(NoSuchMessageException e){ 
       message = key; 
       LOGGER.warn("No message found: "+key); 
      } 
      return message; 
     } 

     public Map<String,String> getMessages(Locale locale){ 
      Properties properties = ((XmlWebApplicationContext)messageSource).getBean("messageSource", 
        ExposedResourceMessageBundleSource.class).getMessages(locale); 
      Map<String,String> messagesMap = new HashMap<String,String>(); 
      for(Map.Entry<Object,Object> entry: properties.entrySet()){ 
       if(entry.getKey() != null && entry.getValue() != null) { 
        messagesMap.put(entry.getKey().toString(), entry.getValue().toString()); 
       } 
      } 
      return messagesMap; 
     } 
    } 

конфигурации Spring:

<bean id="messageSource" class="your.package.ExposedResourceMessageBundleSource"> 
      <property name="basenames"> 
      <list> 
       <value>classpath:yourFileName</value> 
       <value>classpath:yourNextFileName</value> 
      </list> 
      </property> 
      <property name="defaultEncoding" value="UTF-8"/> 
      <property name="cacheSeconds" value="10"/> //If you want reload message every couple seconds. In this case every 10 seconds. 
</bean> 

И ваш @Controller (по аналогии с этим):

@Component 
@RequestMapping("/bundle") 
public class ResourceBundleController { 

    @Autowired 
    private MessageResolveService messageResolveService; 


    @RequestMapping(value = "/locales.js") 
    public ModelAndView strings(HttpServletRequest request) { 

     // Call the string.jsp view 
     return new ModelAndView("/WEB-INF/includes/locales.jsp", "keys", messageResolverService.getMessages(LocaleContextHolder.getLocale())); 
} 
+0

Просто обновленный код –

+0

Спасибо Pawel за ответ :) вы потрясающие. но у меня проблема с перезагрузкой ресурсов. если я изменяю значение из моего файла свойств, значение не обновляется на карте! также я установил cacheSeconds в 15. привет. –

+0

проблема getMergedProperties (locale) .getProperties() не перезагружает результат. но если я использую getMessage (...), он вернет правильное значение. –