Spring - get all resolvable message keys
Well, I "solved" my problem by extending ResourceBundleMessageSource.
package org.springframework.context.support;import java.util.Locale;import java.util.ResourceBundle;import java.util.Set;public class ExposedResourceBundleMessageSource extends ResourceBundleMessageSource { public Set<String> getKeys(String basename, Locale locale) { ResourceBundle bundle = getResourceBundle(basename, locale); return bundle.keySet(); }}
Now I have access to the keys, but I have to do an ugly cast in my controller, in addition to having to specify the message source basename. Ugh, that's a lot of coupling.
Set<String> keys = ((ExposedResourceBundleMessageSource) messageSource).getKeys("messages", locale);
I have solve this issue.
public class ExposedResourceBundleMessageSource extends ResourceBundleMessageSource { public static final String WHOLE = "whole"; private Set baseNames; private Map> cachedData = new HashMap>(); public Set getKeys(String baseName, Locale locale) { ResourceBundle bundle = getResourceBundle(baseName, locale); return bundle.keySet(); } public Map getKeyValues(String basename, Locale locale) { String cacheKey = basename + locale.getCountry(); if (cachedData.containsKey(cacheKey)) { return cachedData.get(cacheKey); } ResourceBundle bundle = getResourceBundle(basename, locale); TreeMap treeMap = new TreeMap(); for (String key : bundle.keySet()) { treeMap.put(key, getMessage(key, null, locale)); } cachedData.put(cacheKey, treeMap); return treeMap; } public Map getKeyValues(Locale locale) { String cacheKey = WHOLE + locale.getCountry(); if (cachedData.containsKey(cacheKey)) { return cachedData.get(cacheKey); } TreeMap treeMap = new TreeMap(); for (String baseName : baseNames) { treeMap.putAll(getKeyValues(baseName, locale)); } cachedData.put(cacheKey, treeMap); return treeMap; } public void setBasenames(String[] basenames) { baseNames = CollectionUtils.arrayAsSet(basenames); super.setBasenames(basenames); }}
My solution:
use spring
<util:properties />
<util:properties id="message" location="classpath:messages.properties" />
Add an interceptor, with 'message' set to request attributes
request.setAttribute("msgKeys", RequestContextUtils.getWebApplicationContext(request).getBean("message"));
In JSP, use the
msgKeys
to retrieve message through<fmt:message />
tagvar msg = {<c:forEach items="${msgKeys}" var="m" varStatus="s"> <c:set var="key" value="${fn:substringBefore(m,'=')}"/> "${fn:substringAfter(key)}":"<fmt:message key="${key}"/>",</c:forEach>};
(Of course you need to further escape the output to match js string.)
So, for properties
app.name=Application Nameapp.title=Some title
would output
var msg = { "name":"Application Name", "title":"Some title" };
The good thing about that is that you can do some more logic in c:forEach
loop.