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

从上面两幅图可以看出在切换中英文时有五个部分的内容发送改变。分别是:用户名(Username)、密码(Password)、记住我(Remember Me)、登录(Sign)、重置(Rest)。
第一部分、先在resources目录下新建一个i18n文件夹,并在该文件夹下新建一个Resource Bundle.如下图所示:

并在跳出的弹框内写入以下信息:

点击“OK”后就会在i18n目录下生成3个后缀名为“.properties”的文件。如下所示:

第二部分、分别在这三个文件中填入相应信息。
login.properties表示默认显示的信息。login.password、login.remember、login.reset、login.submit、login.username是自己设置的key值,用于在HTML中显示。后面的是将要显示的内容。
login.password=密码
login.remember=记住我
login.reset=重置
login.submit=登录
login.username=用户名
login_en_US.properties
login.password=Password
login.remember=Remember Me
login.reset=Rest
login.submit=Sign
login.username=Username
login_zh_CN.properties
login.password=密码
login.remember=记住我
login.reset=重置
login.submit=登录
login.username=用户名
第三部分、在HTML相应位置填入key值,并在点击“中文”或“English”发出不同请求信息。
注意:在这个项目中使用的模板是thymeleaf,因此需要现在开始的html标签内引入该模板的标签。
根据thymeleaf的文档
显示国际化信息时用到的“#{}”而不是"${}"。
由于这个“记住我”是<input>单标签的没有标签体,根据thymeleaf文档发现需要使用"[[#{}]]"或“[(#{})]”行内表达式。
当点击“中文”时附带请求信息“zh_CN”,点击英文时附带请求信息“en_US”.
login.html代码如下所示:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en" th:replace="main/public :: #public_head"> </head>
<body class="login_bg">
<section class="loginBox">
<header class="loginHeader">
<h1>轻舟万里账单管理系统</h1>
</header>
<section class="loginCont">
<!--<div style="color:red; margin-left: 130px">用户名错误!</div>-->
<form class="loginForm" action="../main/index.html"> <div class="inputbox">
<label for="user" th:text="#{login.username}">Username</label>
<input id="user" type="text" name="username" required/>
</div>
<div class="inputbox">
<label for="mima" th:text="#{login.password}">Password</label>
<input id="mima" type="password" name="password" required/>
</div>
<div class="subBtn">
<input type="checkbox"> [[#{login.remember}]]
</div>
<br/>
<div class="subBtn">
<input type="submit" th:value="#{login.submit}" value="Sign" />
<input type="reset" th:value="#{login.reset}" value="Reset"/>
</div>
<br/>
<div style="margin-left: 100px;">
<a href="#" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a href="" th:href="@{/index.html(l='en_US')}">English</a>
</div>
</form>
</section>
</section>
</body>
</html>
login.html
第四部分、设置区域解析器
在页面上显示中文还是英文是由请求信息头中“accept-language”的决定的,默认是中文。我们只要将点击所附带的请求信息传递给“accept-language”就会使页面的中英文改变。
spring boot中有一个WebMvcAutoConfiguration类,提供了本地区域解析器。如下图所示:

该本地区域解析器上有个注解@ConditionalOnMissingBean表示如果容器中没有这个bean,就将这个bean放到容器中,如果有就使用已经存在的。
从下面的代码片段中可以看到有一个请求头本地区域解析器AcceptHeaderLocaleResolver实现了LocaleResolver接口。

因此我们可以在component包下新建一个自定义区域解析器MyLocaleResolver,该类需要实现接口LocaleResolver,重写方法,根据请求的参数构造一个Local返回。
package club.nipengfei.springboot.component; import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale; /**
* 自定义区域解析器
*/
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
// 获取自定义请求头信息
String l = httpServletRequest.getParameter("l");
// 获取系统默认的区域信息
Locale locale = Locale.getDefault();
if (!StringUtils.isEmpty(l)){
String[] split = l.split("_");
// 接收第一个参数为语言代码,第二个参数为国家代码
locale = new Locale(split[0],split[1]);
}
return locale;
} @Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { }
}
将其添加到容器中,在config包下新建一个MySpringMvcConfigure,在该类的localeResolver方法中返回LocaleResolver,注意使用注解@Bean。代码如下所示:
package club.nipengfei.springboot.config; import club.nipengfei.springboot.component.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class MySpringMvcConfigure { @Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() { // 添加视图控制器
@Override
public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("/main/login");
registry.addViewController("/index.html").setViewName("/main/login");
}
};
} // 区域解析器
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
第五部分、在这过程中遇到的问题。
- 中英文显示乱码,解决方法是修改properties文件编码,改为UTF-8。参考:解决 IntelliJ IDEA 中 i18n国际化 中文乱码问题。
- 无法访问到login页面,因为login.html页面在template/main目录下。解决方法是添加视图控制器。
一个简单的示例在spring boot中实现国际化的更多相关文章
- Spring Boot中使用Spring-data-jpa让数据访问更简单、更优雅
在上一篇Spring中使用JdbcTemplate访问数据库中介绍了一种基本的数据访问方式,结合构建RESTful API和使用Thymeleaf模板引擎渲染Web视图的内容就已经可以完成App服务端 ...
- 【swagger】1.swagger提供开发者文档--简单集成到spring boot中【spring mvc】【spring boot】
swagger提供开发者文档 ======================================================== 作用:想使用swagger的同学,一定是想用它来做前后台 ...
- Spring Boot中整合Sharding-JDBC单库分表示例
本文是Sharding-JDBC采用Spring Boot Starter方式配置第二篇,第一篇是读写分离讲解,请参考:<Spring Boot中整合Sharding-JDBC读写分离示例> ...
- 徒手撸一个 Spring Boot 中的 Starter ,解密自动化配置黑魔法!
我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中.Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小 ...
- Spring Boot中只能有一个WebMvcConfigurationSupport配置类
首先将结论写文章的最前面,一个项目中只能有一个继承WebMvcConfigurationSupport的@Configuration类(使用@EnableMvc效果相同),如果存在多个这样的类,只有一 ...
- Spring Boot中使用Swagger2构建API文档
程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...
- Spring Boot中使用MyBatis注解配置详解(1)
之前在Spring Boot中整合MyBatis时,采用了注解的配置方式,相信很多人还是比较喜欢这种优雅的方式的,也收到不少读者朋友的反馈和问题,主要集中于针对各种场景下注解如何使用,下面就对几种常见 ...
- spring boot中使用@Async实现异步调用任务
本篇文章主要介绍了spring boot中使用@Async实现异步调用任务,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 什么是“异步调用”? “异步调用”对应的是“同步 ...
- (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...
随机推荐
- MATLAB相机标定转XMl代码
function writeXML(cameraParams,file) %writeXML(cameraParams,file) %功能:将相机校正的参数保存为xml文件 %输入: %cameraP ...
- python中的__call__方法
在Python中,函数其实是一个对象: >>> f = abs >>> f.__name__ 'abs' >>> f(-) 由于 f 可以被调用, ...
- 学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式
状态变化模式:在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定.状态变化模式为这一问题提供了一种解决方案. 典型模式:状态模式(State).备忘录 ...
- Java每日一面(Part1:计算机网络)[19/11/25]
作者:晨钟暮鼓c个人微信公众号:程序猿的月光宝盒 1. HTTP相关[2] 1.1Get请求和Post请求的区别 从三个层面来回答: 1.1.1 从HTTP报文层面: Get请求将请求信息放在UR ...
- 万恶之源-python的进化
列表 列表的增删改查 3. 列列表的嵌套 元组和元组嵌套 5. range ⼀一. 列表 1.1 列表的介绍 列表是python的基础数据类型之⼀一 ,其他编程语⾔言也有类似的数据类型. 比如JS中的 ...
- 新闻实时分析系统Hive与HBase集成进行数据分析 Cloudera HUE大数据可视化分析
1.Hue 概述及版本下载 1)概述 Hue是一个开源的Apache Hadoop UI系统,最早是由Cloudera Desktop演化而来,由Cloudera贡献给开源社区,它是基于Python ...
- 23种GoF设计模式概述
23种GoF设计模式概述 在前面,我们对 GoF 的 23 种设计模式进行了分类,这里先对各个设计模式的功能进行简要介绍,以便有个大概了解.后面的章节再进行详细介绍. 创建型模式 关注于怎么创建对象的 ...
- postgresql修改最大连接数配置
1.查看配置文件位置等信息,用来确定配置对应的配置文件. select setting,boot_val,reset_val,sourcefile,*from pg_settings where n ...
- [CSS七分钟系列]都1902年了,还不知道用margin:auto给flex容器内元素分组?
最近看到几篇博文讲解margin:auto在flex容器中的使用,可惜的是大多讲解都浮于页面表现,没深究其中的作用机理,本文在此浅薄对其表现机理做简单探讨. 引子 日常业务迭代过程中,flex已经是前 ...
- [需求设计]从一个小需求感受Redis的独特魅力
分享一个简单的小需求应该怎么设计实现以及有关Redis的使用 Redis在实际应用中使用的非常广泛,本篇文章就从一个简单的需求说起,为你讲述一个需求是如何从头到尾开始做的,又是如何一步步完善的.之前写 ...

