Using multiple resource packages in JSF

I am trying to access multiple resource packages from a JSF page. I have two resource packs:

  • general_messages.properties
  • module_message.properties

I want to access these resource sets in a JSF file. One way to do this is to define specific properties for each of these packages:

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

Is there a way to access these resource sets using the same variable name. Sort of:

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

Or any other better way to access multiple resource packages?

+6
source share
3 answers

You tagged your question with Spring, so I recommend that you use Spring MessageSource. Spring MessageSource can aggregate many property files even hierarchically. This gives you many advantages over the old java ResourceBundle .

You can define Spring MessageSource in spring-config.xml as follows:

 <!-- 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> 

How can you define your Class , which extends the ResourceBundle as follows (some cleaning and refactoring is required):

 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 in faces-config.xml declare your resource package with the class above. Something like that:

 <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> 

Here you go Spring MessageSource in JSF. Hope this is understandable.

+5
source

If two resource packages contain the same key, then which resource packages should be used to resolve this key? So IMO, I don't think the same variable name can be assigned to multiple resource packages.

Perhaps you can combine all .properties into one .properties during the build process (make sure that all keys in the combined properties file are unique, for example, by adding a prefix to each key.). Then you use this single combined .properties throughout the application.

0
source

The only situation I know of in which JSF checks for multiple files for the same package is if you provide packages for multiple locales (see Providing Localization Messages and Shortcuts ).

Perhaps you can specify the f:loadBundle class that extends the ResourceBundle instead of the property file and uses this class to refer to multiple property files. I have not tried this before.

In addition, if you use Seam, it provides the ability to register several "global" packages, as well as bundles that can be associated with one of several types (facelets), all of which can be referenced using messages , for example. #{messages.my_message} as described here (this is for Seam 2, this may be slightly different in Seam 3). I think you are after that.

0
source

Source: https://habr.com/ru/post/893335/


All Articles