听起来很高大上的国际化 其实就是通过浏览器的语言信息来动态显示国际化效果
通俗来说 就是 点击中文按钮的时候显示中文 点击英文按钮的时候显示英文(当然还支持其它语言
国际化的实现步骤:
在SpringBoot内部已经实现了第2步和第3步 它的底层已经配置好了 因此 只须编写国际化配置文件即可
编写国际化配置文件 就是抽取页面需要显示的国际化消息
通俗来说 就是将要"翻译"的文字提取出来
在resources资源目录下创建一个包 用于存放国际化配置文件
然后创建配置文件login.properties
命名格式:页面名_语言代码_国家代码.properties
当IDEA识别到 就会自动切换到国际化视图
这样的话 可直接右键创建国际化配置文件
点击右侧的加号(+)
输入语言代码_国家代码即可 会自动生成配置文件
然后可在配置文件左下角点击Resource Bundle切换视图
点击左上角的加号(+)添加一套语言配置
如此照葫芦画瓢 配置好全部需要转换的语言部分
SpringBoot已经自动配置好了管理国际化资源文件的组件
语言资源自动配置类的底层代码是这样的:
@ConfigurationProperties(prefix = "spring.messages")
public class MessageSourceAutoConfiguration {
/**
* Comma-separated list of basenames (essentially a fully-qualified classpath
* location), each following the ResourceBundle convention with relaxed support for
* slash based locations. If it doesn't contain a package qualifier (such as
* "org.mypackage"), it will be resolved from the classpath root.
*/
private String basename = "messages";
...
}
因此 可以看见 配置文件默认的基础名为messages
基础名就是配置文件去掉例如zh_CN的名称
可用spring.messages来配置
基础名可包含包名 若不包含 则从类路径下寻找
然后去配置文件中配置:
例:spring.messages.basename=i18n.login
该配置路径的意义为 从i18n包下寻找基础名为login的配置文件
目的是为了让SpringBoot能找到我们配置的国际化配置文件
Thymeleaf的#{}
语法就是用来获取国际化信息的
因此 可很方便地获取到国际化后的值
IDEA中默认不会将中文转为ASCII码 因此 会导致乱码问题
在设置中 选择File Encoding 然后勾选自动转换ASCII码
这样配置 默认根据的是浏览器的语言
浏览器用什么语言 就自动识别 然后作为默认语言
这个功能在一些外贸网站上比较常见
原理:
国际化的Locale区域信息对象里面有个LocaleResolver组件 用于获取区域信息对象
SpringBoot默认也配置了区域信息解析器
底层代码:
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
意思就是 当指定固定的区域解析器时 就使用固定的 否则使用AcceptHeaderLocaleResolver
而AcceptHeaderLocaleResolver是从浏览器的请求头中获取Locale信息 然后进行国际化
因为 浏览器在发送请求时 请求头中会带有一个Accept Language字段 里面有浏览器的默认语言
AcceptHeaderLocaleResolver就是通过这个来识别浏览器默认语言的
因此 只需将LocaleResolver替换即可
在前端 需要在切换按钮的链接上携带区域信息
<a class="btn btn-sm" th:href="@{/index.html(language=zh_CN)}">中文a>
<a class="btn btn-sm" th:href="@{/index.html(language=en_US)}">Englisha>
当点击切换语言链接的时候 就会带上语言参数来发送请求
这样 URL后面就能携带区域信息了:
http://ip:端口/XXXX/index.html?language=zh_CN
然后 在后端 须创建一个自己的区域解析器类 实现LocaleResolver接口
直接上代码:
public class MyLocaleResolver implements LocaleResolver {
// 解析区域信息
@Override
public Locale resolveLocale(HttpServletRequest request) {
// 从URL的参数中获取区域信息
String language = request.getParameter("language");
// 区域信息默认用系统识别的
Locale locale=Locale.getDefault();
// 若获取的区域参数不为空 即 URL带有区域信息
if (!StringUtils.isEmpty(language))
{
// 根据中间的下划线分隔成两部分
String[] s = language.split("_");
locale=new Locale(s[0],s[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
然后在自己写的配置类中添加自己的区域解析器类到Spring容器中(记得加@Bean注解)
@Bean
public LocaleResolver localeResolver()
{
// 直接返回自己配置的区域解析器
return new MyLocaleResolver();
}
如此配置 自己的区域解析器就能正常工作了 会替代掉SpringBoot自带的区域解析器
最终达到的效果就是 当URL带有区域信息 则使用指定的语言 当URL不带有区域信息 则自动根据浏览器语言进行识别