是否可以编写自定义JSP标记来获取i18n消息密钥并输出给定请求的翻译短语?
通常在JSP / JSTL中,我这样做:
<fmt:message key="${messageKey}"><fmt:param>arg1</fmt:param></fmt:message>
我得到了翻译短语。现在我需要做以下事情(这是有充分理由的):
<custom:translate key="${messageKey}" arg="arg1"/>
但我不知道如何在自定义代码中查找翻译。 TagSupport基类提供了一个pageContext,我可以从中获得一个具有Locale的ServletRequest ......但是如何查找一个密钥的翻译呢?
我使用Spring 3.0,在我的application-context.xml中,我已经定义了一个ReloadableBundleMessageSource,所以我可以调用:
messageSource.getMessage(
key, new Object[] {arg}, pageContext.getRequest().getLocale()
);
但我不认为我可以将messageSource注入自定义标记,是吗?否则我可以实例化一个新的,但是它会为每次调用加载我的成千上万的翻译吗?我不想诉诸于使messageSource成为静态类的静态成员。
答案 0 :(得分:2)
我不做Spring,但在“普通”JSP中,你可以在ResourceBundle
或Filter
Servlet
实例放在会话范围内
ResourceBundle bundle = ResourceBundle.getBundle(basename, request.getLocale());
request.getSession().setAttribute("bundle", bundle);
在JSP中像对待EL中的任何其他bean一样对待它。
${bundle[messageKey]}
必须有Spring可以将它作为bean放在会话范围内。
答案 1 :(得分:1)
Spring中有一个实用程序可以访问Web应用程序上下文。然后,您可以按名称或类型查找bean。 要掌握资源包,您可以执行以下操作:
WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());
messageResource = springContext.getBean("messageResource");
答案 2 :(得分:0)
这个问题已经很久了,但我认为值得分享另一种方法来解决这个问题。
要在自定义标记中访问Spring消息源,您只需要扩展类org.springframework.web.servlet.tags.RequestContextAwareTag而不是TagSupport。
在这种情况下,您必须实现方法doStartTagInternal()而不是doStartTag(),但在此方法中,您将可以通过getRequestContext()。getMessageSource()方法访问MessageSource。
因此,您的课程将如下所示:
public class CreateCustomFieldTag extends RequestContextAwareTag{
//variables (key, arg...), getters and setters
@Override
protected int doStartTagInternal() throws Exception {
getRequestContext().getMessageSource().getMessage(
key, new Object[] {arg}, getRequestContext().getLocale());
}
}