在JSP自定义标记中进行i18n转换

时间:2010-09-15 02:36:00

标签: spring jsp internationalization jstl jsp-tags

是否可以编写自定义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成为静态类的静态成员。

3 个答案:

答案 0 :(得分:2)

我不做Spring,但在“普通”JSP中,你可以在ResourceBundleFilter

的帮助下将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());
   }
}