【问题标题】:Why does Thymeleaf International only works with ResourceBundleMessageSource为什么 Thymeleaf International 仅适用于 ResourceBundleMessageSource
【发布时间】:2016-04-23 20:51:39
【问题描述】:

所以在帮助回答这个问题Thymeleaf + Spring (not Boot) - how to show messages from messageSource

我发现如果您使用ReloadableResourceBundleMessageSource,它将无法正常工作。 Thymeleaf 会显示 ??app.name_pt_BR??而不是预期的结果。

@Bean(name = "messageSource")
public MessageSource messageSource() {

    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("/i18n/messages");
    messageSource.setFallbackToSystemLocale(false);
    messageSource.setCacheSeconds(0);
    messageSource.setDefaultEncoding("UTF-8");

    return messageSource;
}

当我切换到下面时,它按预期工作。

@Bean(name = "messageSource")
public MessageSource messageSource() {

    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("/i18n/messages");
    messageSource.setFallbackToSystemLocale(false);
    messageSource.setCacheSeconds(0);
    messageSource.setDefaultEncoding("UTF-8");

    return messageSource;
}

为什么 ReloadableResourceBundleMessageSource 无法使用?

为这个问题添加代码:GitHub

【问题讨论】:

  • 无法重现基于 XML 的配置的问题。 Github 上提供了示例应用程序。基于 Java 的配置似乎有些问题。有other examples使用Java配置成功使用ReloadableResourceBundleMessageSource
  • 有趣...我知道您在哪里使用 Thymeleaf,但您链接的示例不是。但两者都没有使用 Spring Boot。如果这就是问题所在,我会同意。
  • 可能值得在 Spring Github 存储库中提出问题。

标签: java spring thymeleaf


【解决方案1】:

找到答案了!

根据 ReloadableResouceBundleMessageSource 的 javadocs

Spring 特定的 MessageSource 实现,它使用指定的基本名称访问资源包,参与 Spring ApplicationContext 的资源加载。 与基于 JDK 的 ResourceBundleMessageSource 相比,此类使用 Properties 实例作为消息的自定义数据结构,通过 Spring Resource 句柄的 PropertiesPersister 策略加载它们。该策略不仅能够基于时间戳更改重新加载文件,还能够加载具有特定字符编码的属性文件。它也会检测 XML 属性文件。

请注意,设置为“basenames”属性的 basenames 的处理方式与 ResourceBundleMessageSource 的“basenames”属性略有不同。它遵循不指定文件扩展名或语言代码的基本 ResourceBundle 规则,但可以引用任何 Spring 资源位置(而不是仅限于类路径资源)。使用“classpath:”前缀,仍然可以从类路径加载资源,但“-1”以外的“cacheSeconds”值(永久缓存)在这种情况下可能无法可靠地工作。

对于典型的 Web 应用程序,可以将消息文件放入 WEB-INF:例如“WEB-INF/messages”基本名称可以很好地使用“WEB-INF/messages.properties”、“WEB-INF/messages_en.properties”等安排以及“WEB-INF/messages.xml”、“WEB-INF” /messages_en.xml" 等。请注意,由于顺序查找,先前资源包中的消息定义将覆盖后续资源包中的消息定义。

这个 MessageSource 可以很容易地在 ApplicationContext 之外使用:它将使用 DefaultResourceLoader 作为默认值,如果在上下文中运行,它只会被 ApplicationContext 的资源加载器覆盖。它没有任何其他特定的依赖关系。

所以解决方法是提供路径。

来自

@Bean
public MessageSource messageSource()
{
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("messages");
    messageSource.setFallbackToSystemLocale(false);
    messageSource.setCacheSeconds(0);
    messageSource.setDefaultEncoding("UTF-8");
    return messageSource;
}

包含setBasename()上的路径

@Bean
public MessageSource messageSource()
{
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("classpath:messages");
    messageSource.setFallbackToSystemLocale(false);
    messageSource.setCacheSeconds(0);
    messageSource.setDefaultEncoding("UTF-8");
    return messageSource;
}

【讨论】:

  • 但我尝试过它不起作用。如果您有完整的示例,请与我们联系。
  • 什么版本的 Thymeleaf 和 spring boot?这适用于 Thymeleaf 2.1.x 和 spring boot 1.3.x
  • 我正在使用 Thymleaf 3.0.0 和 spring-web 4.3.4
  • 可能是为什么我明白 Thymeleaf 经历了 3.0 的大规模重写。
  • 我发现我的错误我的模板引擎没有设置为@Bean。
猜你喜欢
  • 2011-11-18
  • 2016-01-23
  • 2012-03-23
  • 2011-10-18
  • 1970-01-01
  • 2014-09-23
  • 2018-03-03
  • 1970-01-01
  • 2022-08-19
相关资源
最近更新 更多