JSP и ResourceBundles - PullRequest
       41

JSP и ResourceBundles

4 голосов
/ 19 сентября 2011

Обычно пакеты ресурсов загружаются и используются в JSP с использованием JSTL и fmt, но для этого необходимо всегда использовать синтаксис <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 ]

5 голосов
/ 19 сентября 2011

Да, ниже приводится копия моего ответа на Есть ли сокращение для ? , как упомянуто в комментарии Божо к вашему вопрос. Но так как этот вопрос на самом деле ориентирован на 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 должна указывать на имя файлов комплекта ресурсов, в приведенном выше примере предполагается, что вы text.properties, text_en.properties и т. Д. В пакете 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>

Если вы хотите изменить локаль из какого-либо сервлета или фильтра:

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

Относящиеся / интересно к ноу:

0 голосов
/ 19 сентября 2011

Чтобы сделать то, что вы хотите, вам может потребоваться создать и зарегистрировать свой собственный ELResolver.Взгляните на этот ответ - Альтернатива использованию c: out для предотвращения XSS .

Так что вы можете зарезервировать префикс, такой как MESSAGES, и перевести его в поиск ResourceBundle.

т.е. ${MESSAGES.key} обрабатывается вашим ELResolver как bundle.getString(key).

...