JSP和ResourceBundles

时间:2011-09-19 10:03:56

标签: java jsp servlets internationalization jstl

通常,使用JSTL和fmt在JSP中加载和使用资源包,但这需要始终使用语法<fmt:message key=""/>来访问该值。

当要本地化的文本看起来像 <a href="url" title="message">它很尴尬(虽然写得有效):

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

并且很难使用范围语法

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

有更简单的方法吗?我正在寻找像

这样的东西
<a href="url" title="${messages.key}">

2 个答案:

答案 0 :(得分:5)

是的,下面是我在Is there a shorthand for <fmt:message key="key" />?的答案副本,如Bozho对您的问题的评论所述。但由于这个问题实际上是针对Spring的,我的答案并不完全适用于那里。但是,你的问题不是针对Spring的,而是针对普通的JSP / Servlet,因此不能像精确的dupe那样关闭。所以我认为这里的答案更好:


您可以创建一个extends ResourceBundle的类,使用Filter(基于请求路径?)自行管理加载,并将其存储在会话范围内。 ResourceBundle可以通常的JSP EL方式访问。您可以像Map一样访问它。每次访问都会调用handleGetObject()方法。

这是一个启动示例:

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);
    }

}

(请注意,TEXT_BASE_NAME常量应引用资源包文件的名称,上面的示例假设您text.propertiestext_en.properties等位于{{ 1}}包)

com.example.i18n

Filter

JSP:

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

如果要从某个servlet或过滤器内部更改语言环境:

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

相关/有意思方知:

答案 1 :(得分:0)

要做你想做的事,你可能需要创建并注册自己的ELResolver。看一下这个答案 - Alternative to using c:out to prevent XSS

因此,您可以保留MESSAGES之类的前缀,并将其转换为ResourceBundle查询。

即。 ${MESSAGES.key}ELResolver作为bundle.getString(key)进行处理。