原文鏈接:公衆號狂神說
頁面國際化
準備工作
先在IDEA中統一設置properties的編碼問題!
編寫國際化配置文件,抽取頁面需要顯示的國際化頁面消息。我們可以去登錄頁面查看一下,哪些內容我們需要編寫國際化的配置!
配置文件編寫
1、我們在resources資源文件下新建一個i18n目錄,存放國際化配置文件
2、建立一個login.properties文件,還有一個login_zh_CN.properties;發現IDEA自動識別了我們要做國際化操作;文件夾變了!
3、我們可以在這上面去新建一個文件;
彈出如下頁面:我們再添加一個英文的;
4、接下來,我們就來編寫配置,我們可以看到idea下面有另外一個視圖;
這個視圖我們點擊 + 號就可以直接添加屬性了;我們新建一個login.tip,可以看到邊上有三個文件框可以輸入
我們添加一下首頁的內容!然後依次添加其他頁面內容即可!
然後去查看我們的配置文件;
login.properties :默認
login.btn=登錄
login.password=密碼
login.remember=記住我
login.tip=請登錄
login.username=用戶名
英文:
login.btn=Sign in
login.password=Password
login.remember=Remember me
login.tip=Please log in
login.username=Username
中文:
login.btn=登錄
login.password=密碼
login.remember=記住我
login.tip=請登錄
login.username=用戶名
OK,配置文件步驟搞定!
配置文件生效探究
我們去看一下SpringBoot對國際化的自動配置!這裏又涉及到一個類:MessageSourceAutoConfiguration
裏面有一個方法,這裏發現SpringBoot已經自動配置好了管理我們國際化資源文件的組件 ResourceBundleMessageSource;
// 獲取 properties 傳遞過來的值進行判斷
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
if (StringUtils.hasText(properties.getBasename())) {
// 設置國際化文件的基礎名(去掉語言國家代碼的)
messageSource.setBasenames(
StringUtils.commaDelimitedListToStringArray(
StringUtils.trimAllWhitespace(properties.getBasename())));
}
if (properties.getEncoding() != null) {
messageSource.setDefaultEncoding(properties.getEncoding().name());
}
messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
Duration cacheDuration = properties.getCacheDuration();
if (cacheDuration != null) {
messageSource.setCacheMillis(cacheDuration.toMillis());
}
messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
return messageSource;
}
我們真實 的情況是放在了i18n目錄下,所以我們要去配置這個messages的路徑;
spring.messages.basename=i18n.login
配置頁面國際化值
去頁面獲取國際化的值,查看Thymeleaf的文檔,找到message取值操作爲:#{...}。我們去頁面測試下:
IDEA還有提示,非常智能的!
我們可以去啓動項目,訪問一下,發現已經自動識別爲中文的了
配置國際化解析
在Spring中有一個國際化的Locale (區域信息對象);裏面有一個叫做LocaleResolver (獲取區域信息對象)的解析器!
我們去我們webmvc自動配置文件,尋找一下!看到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 這個類中有一個方法
public Locale resolveLocale(HttpServletRequest request) {
Locale defaultLocale = this.getDefaultLocale();
// 默認的就是根據請求頭帶來的區域信息獲取Locale進行國際化
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;
}
}
}
那假如我們現在想點擊鏈接讓我們的國際化資源生效,就需要讓我們自己的Locale生效!
我們去自己寫一個自己的LocaleResolver,可以在鏈接上攜帶區域信息!
修改一下前端頁面的跳轉連接:
<!-- 這裏傳入參數不需要使用 ?使用 (key=value)-->
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
我們去寫一個處理的組件類!
package com.xiaoyequ.config;
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[] s = l.split("_");
locale = new Locale(s[0], s[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
爲了讓我們的區域化信息能夠生效,我們需要再配置一下這個組件!在我們自己的MvcConofig下添加bean;
package com.xiaoyequ.config;
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.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//擴展springmvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
//自定義的國際化組件生效!!!
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
// 攔截器配置
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/css/**","/js/**","/img/**");
}
}
B站地址:https://space.bilibili.com/95256449