** 原创文章,请勿转载 **

在给spring boot 1.5.6 + thymeleaf 3进行国际化时,踩了一个坑(其实不止一个)。 现象:

看到了吧, 就是取值的key, 后面被加了_en_US 或 _zh_CN, 以及前后的问号。

先看下代码,首先两个资源文件:

messages_en_US.properties

page.content=this is a test string.

message_zh_CN.properties, 在eclipse里打开的,内容是: 这是一个测试字符串

page.content=\u8FD9\u662F\u4E00\u4E2A\u6D4B\u5B57\u7B26\u4E32\u3002

i18n.html:

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>spring boot, thymeleaf 3 国际化</h1>
<hr>
<a href="/i18n?lang=en_US">English</a> | <a href="/i18n?lang=zh_CN">中文</a> <br>
<br>
<br>
<br>
from thymeleaf engine: <span th:text="#{page.content}"></span>
<br>
<br>
from controller model: <span th:text="${content}"></span>
</body>
</html>

其中, #{page.content} 来源于thymeleaf 3,  ${content} 则由controller的Model返回,代码是hardcode, 返回的都是中文

controller:

@Controller
public class I18nController {
@Autowired
private MessageSource messageSource; @GetMapping("/i18n")
public String i18n(Model model) {
String message = messageSource.getMessage("page.content", null, Locale.SIMPLIFIED_CHINESE);
System.out.println("message=" + message);
model.addAttribute("content", message);
return "/i18n";
}
}

从现象看, ${content}这个是没有问题的, 也就是controller里messageSource.getMessage() 是正常的,再也就是说,资源文件是成功加载的,可见,问题出在thymeleaf 3.

再看下thymeleaf 3的配置:

@Configuration
public class ThymeleafConfig implements ApplicationContextAware {
private static final String UTF8 = "UTF-8";
private ApplicationContext applicationContext; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} private SpringResourceTemplateResolver htmlTemplateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("classpath:/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCacheable(false);
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
} @Autowired
private MessageSource messageSource; // 如果显示 ??x_zh_CN??, 缺少spring-context-support
private SpringTemplateEngine templateEngine(SpringResourceTemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
templateEngine.setEnableSpringELCompiler(false); return templateEngine;
} @Bean
public ViewResolver htmlViewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setApplicationContext(applicationContext);
resolver.setTemplateEngine(templateEngine(htmlTemplateResolver()));
resolver.setCharacterEncoding("UTF-8");
return resolver;
} }

** 临时补一句,国际化要spring-context-support包的支持。

web的配置:

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter { @Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
// 默认语言
slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return slr;
} @Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
// 参数名
lci.setParamName("lang");
return lci;
} @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
} // 这个MessageSource可有可无,spring boot默认是有一个的。
// 如果没有自定义messageSource, 要有一个messages.properties文件。
// 如果有这个定义, 就不需要messages.properites
// @Bean
// public ResourceBundleMessageSource messageSource() {
// ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
// messageSource.setBasename("messages");
// return messageSource;
// }
}

查找原因, 在thymeleaf.org上看到这样一段:(在线文档3.1: Using th:text and externalizing text)

thymeleaf叫外部文本,无论是在外部的文件里,或者是在数据库,当然国际化使用的是外部文件。

从这段信息看, thymeleaf使用IMessageResolver接口来加载外部文本的,而且有一个标准的实现:

org.thymeleaf.messageresolver.StandardMessageResolver,所以加载.properties文件应该是和这些信息相关。

但 thymeleaf-spring4 里是怎么用的呢,看下代码吧:

org.thymeleaf.spring4.messageresolver.SpringMessageResolver:

    private final StandardMessageResolver standardMessageResolver;
private MessageSource messageSource; public SpringMessageResolver() {
super();
this.standardMessageResolver = new StandardMessageResolver();
}

它就是使用 org.thymeleaf.messageresolver.StandardMessageResolver, 这样看来,我只要在模板引擎的设置里加上这个IMessageResolver的实现即可,新的代码是这样:

private SpringTemplateEngine templateEngine(SpringResourceTemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
SpringMessageResolver messageResolver = new SpringMessageResolver(); //
messageResolver.setMessageSource(messageSource); // 加入这三行,即为解决方案
templateEngine.setMessageResolver(messageResolver); //
templateEngine.setTemplateResolver(templateResolver);
templateEngine.setEnableSpringELCompiler(false);
return templateEngine;
}

最终呈现:

spring boot + thymeleaf 3 国际化的更多相关文章

  1. Spring Boot Thymeleaf 实现国际化

    开发传统Java WEB工程时,我们可以使用JSP页面模板语言,但是在SpringBoot中已经不推荐使用了.SpringBoot支持如下页面模板语言 Thymeleaf FreeMarker Vel ...

  2. spring boot + Thymeleaf开发web项目

    "Spring boot非常适合Web应用程序开发.您可以轻松创建自包含的HTTP应用.web服务器采用嵌入式Tomcat,或者Jetty等.大多数情况下Web应用程序将使用 spring- ...

  3. Spring boot+Thymeleaf+easyui集成:js创建组件页面报错

    开发工具:Ideal 使用场景:Demo 前提:       环境:Spring boot +Thymeleaf+easyui 引入thymeleaf模板引擎 <html lang=" ...

  4. spring boot: thymeleaf模板引擎使用

    spring boot: thymeleaf模板引擎使用 在pom.xml加入thymeleaf模板依赖 <!-- 添加thymeleaf的依赖 --> <dependency> ...

  5. spring boot + thymeleaf 乱码问题

    spring boot + thymeleaf 乱码问题 hellotrms 发布于 2017/01/17 15:27 阅读 1K+ 收藏 0 答案 1 开发四年只会写业务代码,分布式高并发都不会还做 ...

  6. 一个简单的示例在spring boot中实现国际化

    最近在网上找了一个有关账单管理的spring boot项目,其中有一部分是涉及显示国际化信息的,即将页面上的中英文进行转换.因为在这之前这部分内容没有接触过,所以在这记录下过程. 中文效果图如下所示: ...

  7. Spring Boot Thymeleaf 使用详解

    在上篇文章Spring Boot (二):Web 综合开发中简单介绍了一下 Thymeleaf,这篇文章将更加全面详细的介绍 Thymeleaf 的使用.Thymeleaf 是新一代的模板引擎,在 S ...

  8. 细品 Spring Boot+Thymeleaf,还有这么多好玩的细节!

    @ 目录 1. Thymeleaf 简介 2. 整合 Spring Boot 2.1 基本用法 2.2 手动渲染 3. Thymeleaf 细节 3.1 标准表达式语法 3.1.1 简单表达式 3.1 ...

  9. spring boot thymeleaf 标签未关闭报错

    每天学习一点点 编程PDF电子书免费下载: http://www.shitanlife.com/code spring boot,input标签未关闭报bug,代码稍有不慎就出小问题,后来百度,goo ...

随机推荐

  1. (1)pygame_第一个窗口程序

    ####可以使用python自带的IDLE交互式开发,也可以借助其他的编辑器,我这里采用的pycharm编辑器 1.导入我们所需要的模块 import pygame,sys   --导入我们需要的模块 ...

  2. hdu 1542 线段树 求矩形并

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  3. uva11538

    解题思路: 1. 计数问题, 有三种相对摆放方式: 水平, 竖直, 对角线. 根据加法原理即可, 并且没有交集. 水平和竖直是一样的, 只要n*m矩形旋转90度. 所以结果是: n*m*(m-1)+n ...

  4. python GUI实战项目——tkinter库的简单实例

    一.项目说明: 本次通过实现一个小的功能模块对Python GUI进行实践学习.项目来源于软件制造工程的作业.记录在这里以复习下思路和总结编码过程.所有的源代码和文件放在这里: 链接: https:/ ...

  5. Android开发更新UI的几种方式

    1.runOnUiThread 2.handler post 3.handler sendmessage 4.view post xml布局文件: <RelativeLayout xmlns:a ...

  6. JavaWeb(三)JSP之3个指令、6个动作、9个内置对象和4大作用域

    前言 前面大概介绍了什么是JSP,今天我给大家介绍一下JSP的三个指令.6个动作以及它的9大内置对象.接下来我们就直接进入正题 一.JSP的3个指令 JSP指令(directive)是为JSP引擎而设 ...

  7. Python3常用学习网站总结(随时更新)

    Python资源大全 http://python.jobbole.com/84464/ https://github.com/jobbole/awesome-python-cn   scrapy: h ...

  8. python web框架之Tornado

    说Tornado之前分享几个前端不错的网站: -- Bootstrap http://www.bootcss.com/ -- Font Awesome http://fontawesome.io/ - ...

  9. Spring读书笔记——bean解析

    前情回顾 上篇<Spring读书笔记--bean加载>我们从代码角度介绍了有哪些类负责解析XML文件,又是如何一步步从XML格式脱变成我们熟悉的bean的,直到DefaultBeanDef ...

  10. 数据收集利器 cAdvisor - 每天5分钟玩转 Docker 容器技术(82)

    cAdvisor 是 google 开发的容器监控工具,我们来看看 cAdvisor 有什么能耐. 在 host 中运行 cAdvisor 容器. docker run \ --volume=/:/r ...