【问题标题】:JSP and ResourceBundlesJSP 和资源包
【发布时间】:2011-11-20 02:50:45
【问题描述】:

通常使用 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}">

【问题讨论】:

  • 好吧,我不知道为什么使用 对你来说听起来很“尴尬”。如果您想要上面提到的格式,那么您可以定义自己的 messages bean 并在其中处理本地化,以便您从适当的资源包返回值(根据用户的语言环境)。

标签: java jsp servlets internationalization jstl


【解决方案1】:

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


您可以创建一个extendsResourceBundle 的类,在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 常量应该引用资源包文件的名称,上面的示例假设您在com.example.i18n 包中有text.propertiestext_en.properties 等)

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>

如果您想从某个 servlet 或过滤器中更改语言环境:

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

相关/有趣的知识:

【讨论】:

  • 请注意,使用 'new Text(request.getLocale())' 您将失去缓存功能,并且资源包将在每个请求中重新加载
【解决方案2】:

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

因此,您可以保留一个前缀,例如 MESSAGES,并将其转换为 ResourceBundle 查找。

${MESSAGES.key} 被您的ELResolver 处理为bundle.getString(key)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 2014-04-03
    • 2014-03-24
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多