JSP and ResourceBundles

Usually resource packs are loaded and used in the JSP using JSTL and fmt, but this requires always using the <fmt:message key=""/> syntax.

When the text to be localized looks like this: <a href="url" title="message"> this is inconvenient (although true for writing):

 <a href="url" title="<fmt:message key="key"/>"> 

and embarrassingly using binding syntax

 <fmt:message key="key" var="var"> <a href="url" title="${var}"> </fmt:message> 

Is there an easier way to do this? I'm looking for something like just

 <a href="url" title="${messages.key}"> 
+4
source share
2 answers

Yes, the following is a copy of my answer in Is there an abbreviation <fmt: message key = "key" />? as stated in Bozho's comment on your question. But since this question is actually Spring-targeted, my answer was not fully applicable there. Your question, however, is not Spring-targeted, but just a JSP / Servlet that is targeted and therefore cannot be closed as an exact hoax. So I think the answer is better here:


You can create a class that extends ResourceBundle , manage the loading yourself using Filter (based on the request path?) And save it in the session area. ResourceBundle is available in the usual JSP EL fashion. You can access it as if it were a Map . The handleGetObject() method will be called on every access.

Here is an example run:

 package com.example.i18n; import java.util.Enumeration; import java.util.Locale; import java.util.ResourceBundle; import javax.servlet.http.HttpServletRequest; public class Text extends ResourceBundle { private static final String TEXT_ATTRIBUTE_NAME = "text"; private static final String TEXT_BASE_NAME = "com.example.i18n.text"; private Text(Locale locale) { setLocale(locale); } public static void setFor(HttpServletRequest request) { if (request.getSession().getAttribute(TEXT_ATTRIBUTE_NAME) == null) { request.getSession().setAttribute(TEXT_ATTRIBUTE_NAME, new Text(request.getLocale())); } } public static Text getCurrentInstance(HttpServletRequest request) { return (Text) request.getSession().getAttribute(TEXT_ATTRIBUTE_NAME); } public void setLocale(Locale locale) { if (parent == null || !parent.getLocale().equals(locale)) { setParent(getBundle(TEXT_BASE_NAME, locale)); } } @Override public Enumeration<String> getKeys() { return parent.getKeys(); } @Override protected Object handleGetObject(String key) { return parent.getObject(key); } } 

(note that the constant TEXT_BASE_NAME must refer to the name of the resource package files, the above example assumes that you are text.properties , text_en.properties , etc. in the package com.example.i18n )

Filter :

 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Text.setFor((HttpServletRequest) request); chain.doFilter(request, response); } 

JSP:

 <p>${text['home.paragraph']}</p> 

If you want to change the locale from within a servlet or filter:

 Text.getCurrentInstance(request).setLocale(newLocale); 

Related / Interesting to know:

+5
source

To do what you need, you may need to create and register your own ELResolver . Take a look at this answer - An alternative to using c: out to prevent XSS .

This way you can reserve a prefix like MESSAGES and translate it into a ResourceBundle search.

i.e. ${MESSAGES.key} processed by your ELResolver as bundle.getString(key) .

0
source

All Articles