4

Typically resource bundles are loaded and used within a JSP using JSTL and fmt, but this requires to always use the syntax <fmt:message key=""/> to access the value.

When the text to be localized looks like <a href="url" title="message"> it is awkward (though valid to write):

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

and plain awkward to use the scoped syntax

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

Is there a simpler way to do this? I am looking for something like just

<a href="url" title="${messages.key}">
yannisf
  • 6,016
  • 9
  • 39
  • 61
  • Well, I'm not sure why does using sound so 'awkward' to you. If you want something of the format as you mentioned above, then you can define your own `messages` bean and handle localization within it, such that you return the value from the appropriate resource bundle (as per the user's locale). – Saket Sep 19 '11 at 10:11
  • 1
    related: http://stackoverflow.com/questions/3174373/is-there-and-shorthand-for-fmtmessage-key-key – Bozho Sep 19 '11 at 11:14

2 Answers2

5

Yes, the below is a copy of my answer at Is there a shorthand for <fmt:message key="key" />? as mentioned in Bozho's comment on your question. But since that question is actually Spring-targeted, my answer wasn't fully applicable there. Your question is however not Spring-targeted, but just plain JSP/Servlet targeted and can therefore not be closed as exact dupe. So I think the answer is better at its place here:


You can create a class which extendsResourceBundle, manage the loading yourself with help of a Filter (based on request path?) and store it in the session scope. The ResourceBundle is accessible the usual JSP EL way. You can access it as if it's a Map. The handleGetObject() method will be invoked on every access.

Here's a kickoff example:

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 the TEXT_BASE_NAME constant should refer to name of the resource bundle files, the above example assumes that you've text.properties, text_en.properties, etc in the com.example.i18n package)

The 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 inside some servlet or filter:

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

Related/interesting-to-know:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

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

So you might reserve a prefix such as MESSAGES and translate that into a ResourceBundle lookup.

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

Community
  • 1
  • 1
Paul Grime
  • 14,970
  • 4
  • 36
  • 58