2011-07-22 21 views
6

Estoy intentando acceder a múltiples paquetes de recursos desde una página JSF. Tengo dos paquetes de recursos:Uso de múltiples paquetes de recursos en JSF

  • general_messages.properties
  • module_message.properties

Quiero tener acceso a estos dos paquetes de recursos en un archivo JSF. Una forma de que pueda hacer esto es definir propiedades específicas para cada uno de estos paquetes:

<f:loadBundle basename="com.sample.general_messages" var="general"/> 
<f:loadBundle basename="com.sample.module_message" var="module"/> 

¿Hay alguna manera de acceder a estos dos paquetes de recursos utilizando el mismo nombre de variable. Algo así como:

<f:loadBundle basename="com.sample.general_messages, com.sample.module_message" var="general"/> 

O cualquier otra mejor manera de acceder a múltiples paquetes de recursos?

+0

Estaba pensando si Spring Framework tiene una solución para esto? – Abdul

Respuesta

5

Has etiquetado tu pregunta con Spring, por lo que te recomiendo usar Spring MessageSource. Spring MessageSource puede agregar muchos archivos de propiedades incluso jerárquicamente. Te da muchas ventajas sobre el antiguo java ResourceBundle.

Puede definir la primavera MessageSource en que spring-config.xml así:

<!-- 
Application messages configuration. 
--> 
<bean id="messageSource" name="resourceBundle" 
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource" 
    p:fallbackToSystemLocale="false" 
    p:cacheSeconds="0"> 
    <property name="basenames"> 
     <list> 
      <value>/messages/Messages</value> 
<!--  <value>${application.messages}</value>--> 
     </list> 
    </property> 
</bean> 

de lo que puede definir su Class que se extiende ResourceBundle como esto (necesita un poco de limpieza y refactorización):

public class SpringResourceBundle extends ResourceBundle 
{ 

    private MessageSource messages; 
    private FacesContext fc; 
    private Locale locale = null; 

    public SpringResourceBundle() 
    { 
     fc = FacesContext.getCurrentInstance(); 
     WebApplicationContext webAppCtx = (WebApplicationContext) fc.getExternalContext().getApplicationMap().get(
       WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 
     messages = (MessageSource) webAppCtx.getBean("messageSource"); 
    } 

    @Override 
    public Locale getLocale() 
    { 
     Locale loc = fc.getELContext().getLocale(); 
     if (fc.getExternalContext() != null) { 
      loc = fc.getExternalContext().getRequestLocale(); 
     } 
     try { 
      UIViewRoot viewRoot = fc.getViewRoot(); 
      if (viewRoot != null) { 
       loc = viewRoot.getLocale(); 
      } 
      if (loc == null) { 
       loc = fc.getApplication().getDefaultLocale(); 
      } 

     } catch (Throwable th) { 
      System.out.println(th.getMessage()); 
      loc = locale; 
     } 
     locale = loc; 
     return loc; 
    } 

    @Override 
    protected Object handleGetObject(String key) 
    { 
     try { 
      return messages.getMessage(key, null, getLocale()); 
     } catch (NoSuchMessageException e) { 
      return "???" + key + "???"; 
     } 
    } 

    @Override 
    public Enumeration<String> getKeys() 
    { 
     return Collections.enumeration(Collections.EMPTY_LIST); 
    } 
} 

Finnaly en faces-config.xml declare su paquete de recursos con la clase anterior. Algo como esto:

<application> 
    <locale-config> 
     <default-locale>en</default-locale> 
     <supported-locale>cs</supported-locale> 
     <supported-locale>de</supported-locale> 
     <supported-locale>en</supported-locale> 
    </locale-config> 
    <message-bundle>your.package.SpringResourceBundle</message-bundle> 
</application> 

Aquí tienes Spring MessageSource en JSF.Espero que sea comprensible.

0

Si dos paquetes de recursos contienen la misma clave, ¿qué paquetes de recursos se deben usar para resolver esta clave? Entonces, IMO, no creo que el mismo nombre de variable se pueda asignar a múltiples paquetes de recursos.

Quizás, puede combinar todos los .properties en un solo .properties en su proceso de compilación (asegúrese de que todas las claves en el archivo de propiedades fusionadas son únicas, por ejemplo, agregando algún prefijo en cada clave). A continuación, utilice esta única fusionada .properties en toda la aplicación.

+0

Esa es una de las soluciones, pero si uno tiene que modularizar la aplicación, y cuando hay muchos campos, tener todo en un archivo de propiedades se volverá algo torpe e inmanejable. Realmente debe haber una solución para abordar este problema. Estoy tratando de explorar más sobre cómo hacerlo funcionar. Un alimento rápido para pensar: ¿Spring Framework nos proporciona una solución? – Abdul

0

La única situación (que yo sepa) en la que JSF comprueba varios archivos para el mismo paquete es si está proporcionando paquetes para varias configuraciones regionales (consulte Providing Localized Messages and Labels).

Puede señalar la etiqueta f:loadBundle a una clase que se extiende ResourceBundle en lugar de un archivo de propiedades y utilizar esa clase para hacer referencia a varios archivos de propiedades. Aunque no lo he intentado antes sin embargo.

Además, si está utilizando Seam, ofrece la posibilidad de registrar múltiples paquetes 'globales' así como paquetes que pueden asociarse con una o más vistas (facelets), todos los cuales se pueden referenciar usando messages p. #{messages.my_message} como se describe here (eso es para Seam 2, puede ser un poco diferente en Seam 3). Creo que eso es lo que buscas.

Cuestiones relacionadas