是否有的简写?
写下这样的事情是很乏味和丑陋的:
<input type="button" value="" />
如果您想将消息标记嵌套在另一个标记的属性中,则会变得更糟。
有没有任何简写。 例如(在JSF中):
(适用于spring-mvc的解决方案)
这感觉有点像黑客,但你可以写一个java.util.Map
的自定义实现,当调用get(key)
,它从Spring MessageSource
获取消息。 可以将此Map
添加到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 { 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> entrySet() { // no need to implement this return null; } } }
作为备选:
然后使用${var}
作为常规EL。
如果你想要的只是一个快捷方式,你可以创建一个标签文件,比如说btn.tag
<%@tag%> <%@ attribute name="key" required="true" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> " />
并像这样使用它
<%@ taglib tagdir="/WEB-INF/tags" prefix="tags"%> ... ...
没有。 因为我不做Spring,所以我会在这个答案中将其排除在外。 有关Spring目标的答案,请参阅@skaffman。 您可以创建一个extends
ResourceBundle
的类,借助Filter
(基于请求路径?) Filter
管理加载,并将其存储在会话范围中。 ResourceBundle
可以通常的JSP EL方式访问。 您可以像访问Map
一样访问它。 每次访问时都会调用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 getKeys() { return parent.getKeys(); } @Override protected Object handleGetObject(String key) { return parent.getObject(key); } }
Filter
:
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Text.setFor((HttpServletRequest) request); chain.doFilter(request, response); }
JSP:
${text['home.paragraph']}
如果要从某个servlet或filter内部更改语言环境:
Text.getCurrentInstance(request).setLocale(newLocale);
相关/有意思方知:
- 覆盖
ResourceBundle#Control
以使用UTF-8读取文件 - 列出所有可用的
ResourceBundle
文件 - 迭代
ResourceBundle
多个属性
我找到了一种没有任何拦截器的方法:
${pageScope["org.springframework.web.servlet.tags.REQUEST_CONTEXT"] .getMessage("hello")}
但它太长了,关键的“org.springframework.web.servlet.tags.REQUEST_CONTEXT”可能与所有版本的弹簧不兼容。
我为每种语言使用属性文件,以下工作正常:
您可以使用资源包在servlet或filter中设置msg
请求变量,以通过JSP代码中的EL表达式获取消息${msg.messageKey}
import javax.servlet.jsp.jstl.core.Config; import java.util.ResourceBundle; ... public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { String STR_LOCALE = "es-MX"; // you can get this value from the http request to get the default browser locale. String LOCALE_BASENAME = "my.package.basename"; Locale locale = Locale.forLanguageTag(STR_LOCALE); req.setAttribute("msg", ResourceBundle.getBundle(LOCALE_BASENAME, locale)); // And you can setup the 'fmt' tag library from here to resolve parameterized messages. Config.set(req, Config.FMT_LOCALE, locale); Config.set(req, Config.FMT_LOCALIZATION_CONTEXT, LOCALE_BASENAME); }
例:
... <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> ... ${msg.header}
${msg[variableHeader]}
The value
这在我的java servlet 2.5环境中有效。