【问题标题】:How to use Spring with I18n?如何在 I18n 中使用 Spring?
【发布时间】:2017-07-09 12:17:06
【问题描述】:

我的项目在 github 上:https://github.com/QuentinVaut/JavaquariumEE

我关注了许多说不同内容的教程,我尝试实施教程中的解决方案,但没有错,我明白为什么。

你能告诉我我的项目有什么问题并解释一下吗?

众多教程和 Github 示例之一:

http://memorynotfound.com/spring-mvc-internationalization-i18n-example/

【问题讨论】:

    标签: java spring spring-mvc internationalization thymeleaf


    【解决方案1】:

    我粗略地浏览了那个教程。以下是我的做法:

    首先配置它:

    在返回MessageSource的配置类中创建一个Bean 执行。

    @Bean
    public MessageSource messageSource() //The bean must be named messageSource.
    {
    ReloadableResourceBundleMessageSource messageSource =
    new ReloadableResourceBundleMessageSource();
    messageSource.setCacheSeconds(-1); //cache time in seconds was set to -1. This disables reloading and makes the message source cache messages forever (until the JVM restarts).
    messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
    messageSource.setBasenames(
    "/WEB-INF/i18n/messages", "/WEB-INF/i18n/errors"); //the message source is configured with the basenames /WEB-INF/i18n/messages and /WEB-INF/i18n/errors. This means that the message source will look for filenames like /WEB-INF/i18n/messages_en_US.properties, /WEB-INF/i18n/errors_fr_FR.properties
    return messageSource;
    }
    

    现在创建一个返回 LocaleResolver 的 bean:

    @Bean
    public LocaleResolver localeResolver() //The bean must be named localeResolver.
    {
    return new SessionLocaleResolver();
    }
    

    这使得 LocaleResolver 可用于由 DispatcherServlet 执行的任何代码。这意味着其他非视图 JSP 无权访问 LocaleResolver。为了解决这个问题,您可以创建一个过滤器并像这样进行设置:

    private ServletContext servletContext;
    private LocaleResolver = new SessionLocaleResolver();    
    @Inject MessageSource messageSource;
    ...
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException
    {
    request.setAttribute(
    DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver
    );
    JstlUtils.exposeLocalizationContext(
    (HttpServletRequest)request, this.messageSource
    ); 
    

    现在你需要配置处理程序拦截器:

    您在配置类中覆盖 WebMvcConfigurerAdapter 的 addInterceptors 方法以设置 LocaleChangeInterceptor(或任何其他拦截器):

    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
    super.addInterceptors(registry);
    registry.addInterceptor(new LocaleChangeInterceptor());
    }
    

    现在您可以在控制器上简单地使用@Injected LocaleResolver。您只需在解析器上调用 setLocale 即可更新当前语言环境。

    编辑:更具体的示例:

    假设你有一个简单的控制器:

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Map<String, Object> model)
    {
    model.put("date", new Date());
    model.put("alerts", 12);
    model.put("numCritical", 0);
    model.put("numImportant", 11);
    model.put("numTrivial", 1);
    return "home/index";
    }
    

    然后假设您在 /WEB-INF/i18n/ 下有 messages_en_US.properties 文件。此属性文件包含本地化为美国英语的消息。

    title.alerts=服务器警报页面

    alerts.current.date=当前日期和时间:

    number.alerts=有{0,choice,0#没有警报|1#只有一个警报|1

    alert.details={0,choice,0#没有警报|1#有一个警报|1 \ 警报非常重要。 {1,choice,0#没有警报|1#有一个警报|1

    然后,假设您在 /WEB-INF/i18n/ 下有 messages_es_MX.properties 文件,该文件包含本地化的消息 墨西哥西班牙语。

    title.alerts=服务器警报页面

    alerts.current.date=实际时间: number.alerts={0,choice,0#No hay alertas|1#Hay una alerta|1

    alert.details={0,choice,0#No hay alertas son críticos|1#Una alerta es \ crítica|1

    现在,您需要在您的 JSP 中使用 &lt;spring:message&gt; 标签来进行英语和西班牙语之间的翻译。这是您的 jsp 页面的外观:

    <spring:htmlEscape defaultHtmlEscape="true" />
    <%--@elvariable id="date" type="java.util.Date"--%>
    <%--@elvariable id="alerts" type="int"--%>
    <%--@elvariable id="numCritical" type="int"--%>
    <%--@elvariable id="numImportant" type="int"--%>
    <%--@elvariable id="numTrivial" type="int"--%>
    
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    
    <!DOCTYPE html>
    <html>
    <head>
    <title><spring:message code="title.alerts" /></title>
    </head>
    <body>
    <h2><spring:message code="title.alerts" /></h2>
    <i><fmt:message key="alerts.current.date">
    <fmt:param value="${date}" />
    </fmt:message></i><br /><br />
    <fmt:message key="number.alerts">
    <fmt:param value="${alerts}" />
    </fmt:message><c:if test="${alerts > 0}">
    &nbsp;<spring:message code="alert.details">
    <spring:argument value="${numCritical}" />
    <spring:argument value="${numImportant}" />
    <spring:argument value="${numTrivial}" />
    </spring:message>
    </c:if>
    </body>
    </html>

    【讨论】:

    • 如何实现 doFilter 方法?在我的 MvcConfig 中?
    • 没有。这是您在创建实现过滤器接口的类时覆盖的方法。我们称该类为过滤器。您可以查看如何在 Spring 项目中进行设置。但是您可能根本不需要添加过滤器。如果某些jsp不显示翻译,我只是把它放在那里。
    • @QuentinV 首先尝试不创建过滤器,如果这不起作用。然后是的,看看如何创建一个过滤器以及如何在 Spring MVC 项目中设置它。你会发现很多关于它的教程。但首先尝试不使用它。
    • 我已经在我的 MvCConfig 中添加了你的 messageSource、localeResolver 和 addInterceptor,但我认为消息:UC01_especes javaquarium.welcome 什么也没显示。在我的 Github 链接上查找文件 MvcConfig.java
    • 我刚刚在我的回答中添加了更多细节。你可以试试
    【解决方案2】:

    在我的 application.properties 中,我添加了这一行:

    spring.messages.basename=i18n/messages
    spring.messages.cache-seconds=-1
    spring.messages.encoding=UTF-8
    

    您可以使用此删除 MessageSource bean。

    在我使用之前

     <spring:message code="javaquarium.welcome" text="default text" />
    

    但我有 thymleaf 需要这条线:

    <h1 th:text="#{javaquarium.welcome}"></h1>
    

    现在来自 messages.properties 的消息正确显示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2020-05-13
      • 2012-02-16
      • 1970-01-01
      • 2018-05-11
      • 2012-01-18
      • 1970-01-01
      相关资源
      最近更新 更多