Существует ли сокращение от <fmt:message ключ = “ключ”/>?

Это утомительно и ужасно для записи вещей как:

<input type="button" value="<fmt:message key="submitKey" />" />

И в случае, если Вы хотите вложить тег сообщения в атрибуте другого тега, это становится еще хуже.

Есть ли любое сокращение от этого. Например (как в JSF):

<h:commandButton value="#{msg.shareKey}" />

(spring-mvc-only применимые решения)

18
задан kiamlaluno 19 September 2011 в 13:42
поделиться

3 ответа

Это похоже на взлом, но вы можете написать собственную реализацию java.util.Map , которая при вызове get (key) извлекает сообщение из Spring MessageSource . Эту карту можно добавить в модель с помощью ключа msg , что позволит вам разыменовать сообщения с помощью $ {msg.myKey} .

Возможно, существует какая-то другая динамическая структура, отличная от распознаваемой JSP EL, которая не является Map , но я не могу придумать ни одной насквозь.

public class I18nShorthandInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = Logger.getLogger(I18nShorthandInterceptor.class);

    @Autowired
    private MessageSource messageSource;

    @Autowired
    private LocaleResolver localeResolver;

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {

        request.setAttribute("msg", new DelegationMap(localeResolver.resolveLocale(request)));

        return true;
    }

    private class DelegationMap extends AbstractMap<String, String> {
        private final Locale locale;

        public DelegationMap(Locale locale) {
            this.locale = locale;
        }

        @Override
        public String get(Object key) {
            try {
                return messageSource.getMessage((String) key, null, locale);
            } catch (NoSuchMessageException ex) {
                logger.warn(ex.getMessage());
                return (String) key;
            }
        }
        @Override
        public Set<Map.Entry<String, String>> entrySet() {
            // no need to implement this
            return null;
        }

    }
}

В качестве альтернативы:

<fmt:message key="key.name" var="var" />

Затем используйте $ {var} как обычный EL.

12
ответ дан 30 November 2019 в 09:03
поделиться

Нет. Поскольку я не использую Spring, я оставлю это вне контекста в этом ответе. Для ответа, ориентированного на Spring, см. @Skaffman. Вы можете создать класс, который расширяет ResourceBundle , управлять загрузкой самостоятельно с помощью Filter (на основе пути запроса?) И сохранять его в области сеанса. ResourceBundle доступен обычным способом JSP EL. Вы можете получить к нему доступ, как если бы это Карта .Метод handleGetObject () будет вызываться при каждом доступе.

Вот начальный пример:

package com.example;

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

}

Фильтр :

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

Связанные / интересные-для -know:

3
ответ дан 30 November 2019 в 09:03
поделиться

Если вам нужен только ярлык, вы можете создать файл тегов, скажем, btn.tag

<%@tag%>
<%@ attribute name="key" required="true" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

<input type="button" value="<fmt:message key="${key}" />" />

, и использовать его так

<%@ taglib tagdir="/WEB-INF/tags" prefix="tags"%>
...
<tags:btn key="submitKey" >
...
4
ответ дан 30 November 2019 в 09:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: