🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
国际化就是根据需要能够将网站的语言切换为当地语言信息,如可以将网站在中英文之间进行切换。 ![](https://img.kancloud.cn/75/7b/757b303ef465cebba75d251a98062b78_654x291.gif) 我们可以实现根据浏览器使用的默认语言来实现网站语言的切换,或定制我们的区域信息解析器来实现点击链接切换语言。 <br/> 步骤如下: **1. 明确需要国际化的地方** 假如我需要将`templates/international.html`页面进行国际化。 ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <!-- international.title 是下面国际化配置文件的属性名 --> <title th:text="#{international.title}">国际化</title> </head> <body> <h1 th:text="#{international.location}">当前在中国</h1> <!-- 需要传递一个l的参数让后台知道要使用的是哪种语言 --> <a th:href="@{/international(l=zh_CN)}">中文</a> <a th:href="@{/international(l=en_US)}">English</a> </body> </html> ``` **2. 编写国际化配置文件** 国际化配置文件统一使用`.properties`来编写,命令规则为:`页面名_语言_国家编码`,如中文配置文件:`international_zh_CN.properties`、英文(美国)`international_en_US.properties`。 先创建三个空的国际化配置文件,如下图: ![](https://img.kancloud.cn/cc/e2/cce2c38d9c19f4f690a6cfafedc6cd25_1227x670.png) `international.properties`的作用是当没有提供对应的国际化配置文件时,默认采用该配置文件。 ![](https://img.kancloud.cn/ef/25/ef25b08cfe17be95c9615f3c1ee7e65d_915x464.png) 最终填写如下: **`resources/i18n/international.properties`** ```xml international.location=当前在中国~~~ international.title=国际化~~~~ ``` **`resources/i18n/international_zh_CN.properties`** ```xml international.location=当前在中国 international.title=国际化 ``` **`resources/i18n/international_en_US.properties`** ```xml international.location=Currently in the United States international.title=International ``` **3. 指定国际化配置文件的位置** 国际化配置文件默认在`resources`目录,但是我们更改为`resources/i18n/`目录,所以需要指定。 **`resources/application.properties`** ```xml # 当你有多个国际化配置文件时用 , 隔开 spring.messages.basename=i18n.login, i18n.international ``` **4. 启动项目访问`international.html`页面** 当你访问到该页面,由浏览器的默认语言来决定使用哪个配置文件。下图为我的谷歌浏览器默认的语言为简体中文,所以采用是`international_zh_CN.properties`的配置信息。 ![](https://img.kancloud.cn/90/14/90143c46b240fc9e102af3c1932ff6f1_919x224.png) 上面网站的语言由浏览器当前的默认语言决定,但是我们可以在页面放置链接任意在中英文之间切换。 其原理是:可以使用区域信息解析器LocaleResolver来获取国际化Locale,它的部分源码如下: ```java -----WebMvcAutoConfiguration----- public LocaleResolver localeResolver() { // 如果没有指定区域信息,则使用默认的FIXED if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) { return new FixedLocaleResolver(this.mvcProperties.getLocale()); } else { // 如果没有指定,则从AcceptHeaderLocaleResolver获取区域信息 AcceptHeaderLocaleResolver localeResolver = ▲▲▲▲new AcceptHeaderLocaleResolver();▲▲▲▲ localeResolver.setDefaultLocale(this.mvcProperties.getLocale()); return localeResolver; } } -----AcceptHeaderLocaleResolver----- public Locale resolveLocale(HttpServletRequest request) { Locale defaultLocale = this.getDefaultLocale(); if (defaultLocale != null && request.getHeader("Accept-Language") == null) { return defaultLocale; } else { // 从请求头中获取区域信息 ▲▲▲▲Locale requestLocale = request.getLocale();▲▲▲▲ List<Locale> supportedLocales = this.getSupportedLocales(); if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) { Locale supportedLocale = this.findSupportedLocale(request, supportedLocales); if (supportedLocale != null) { return supportedLocale; } else { return defaultLocale != null ? defaultLocale : requestLocale; } } else { return requestLocale; } } } ``` 在浏览器中按F12,找到任意一个请求,可以看到请求头部的语言信息,我们需要定制自己的信息解析器来解析的请求头部信息。 ![](https://img.kancloud.cn/cd/4b/cd4bd3d01810271a217e2c3f1854a017_965x396.png) **5. 实现我们自己的区域信息解析器** *`com.example.webresult.component.MyLocaleResolver`* ```java package com.example.webresult.component; import org.apache.tomcat.jni.Local; 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 request) { // 获取从前端请求的参数l String l = request.getParameter("l"); // 如果没有请求参数l,则使用默认区域 Locale local = Locale.getDefault(); if (!StringUtils.isEmpty(l)) { String[] split = l.split("_"); // 创建我们自己的区域,(国家语言, 国家编码) local = new Locale(split[0], split[1]); } return local; } @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } } ``` **6. 将定制的区域信息解析器注册到IoC容器中** 需要将上面定制的区域信息解析器注册到IoC容器中,让我们的区域信息解析器起效,覆盖SpringMVC默认的解析器。 *`com.example.webresult.config.MyMvcConfig`* ```java package com.example.webresult.config; import com.example.webresult.component.MyLocaleResolver; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; // 如果使用@EnableWebMvc则是完全取代该父类的自动配置 // @EnableWebMvc @Configuration public class MyMvcConfig implements WebMvcConfigurer { /** * 将我们的区域解析器注入到IoC容器中,覆盖SpringMVC默认的解析器 * @return */ @Bean public LocaleResolver localeResolver() { return new MyLocaleResolver(); } } ``` **7. 我编写的controller如下** *`com.example.webresult.controller.IndexController`* ```java package com.example.webresult.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HelloController { @RequestMapping(value = "/international") public String international() { return "international"; } } ``` 启动项目后访问:http://localhost:8080/international 显示如下: ![](https://img.kancloud.cn/75/7b/757b303ef465cebba75d251a98062b78_654x291.gif)