【问题标题】:i18n translation in JSP custom tagJSP 自定义标签中的 i18n 翻译
【发布时间】:2011-04-12 11:21:32
【问题描述】:

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

【问题讨论】:

  • 同样的问题 - 我在几个不同的 JSP 中有逻辑,它们根据 bean 中的值确定项目的状态,并且更愿意将其设为自定义标记,但我不确定如何从我的 messages.properties 文件中获取人性化的“状态”。我想一种选择是让标签返回消息密钥,然后在 标签中使用它,但这看起来非常混乱......
  • 这实际上是我最终所做的,将消息键和参数数组作为 2 个单独的新 pageContext 属性返回。然后我做了一个

标签: spring jsp internationalization jstl jsp-tags


【解决方案1】:

我不使用 Spring,但在“普通”JSP 中,您可以借助 FilterServletResourceBundle 实例放入会话范围内

ResourceBundle bundle = ResourceBundle.getBundle(basename, request.getLocale());
request.getSession().setAttribute("bundle", bundle);

在 JSP 中将其视为 EL 中的任何其他 bean。

${bundle[messageKey]}

必须有可能让 Spring 将其作为 bean 放入会话范围内。

【讨论】:

  • hmmm.. 如何从具有参数的 ResourceBundle 中获取消息?与附加到每个会话相比,将其作为模型属性附加到每个页面可能更容易。
  • 哦,对不起,我忽略了那部分。您可以使用MessageFormat#format() 做到这一点。是的,你当然也可以把它放在请求范围内。毕竟,在每个 HTTP 请求上创建一个新请求只是稍微贵一点。
【解决方案2】:

spring 中有一个实用程序可以访问 Web 应用程序上下文。然后,您可以通过名称或类型查找 bean。 要获取资源包,您可以执行以下操作:

WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());
messageResource = springContext.getBean("messageResource");

【讨论】:

    【解决方案3】:

    这个问题很老了,但我认为值得分享另一种解决方法。

    要在自定义标签中访问 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());
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多