本文章主要分爲兩個部分:
- freemarker的國際化相關配置
- Spring Boot的國際化相關配置
freemarker國際化配置
頁面模板
使用.ftl文件作爲靜態化模板,這裏不多做解釋,這裏主要說明國際化所需配置
<!-- 1.國際化添加導入 -->
<#import "/spring.ftl" as spring/>
<#include "/admin/utils/ui.ftl"/>
<@layout>
<div class="table-responsive">
<table id="dataGrid" class="table table-striped table-bordered">
<thead>
<tr>
<th width="80">#</th>
<!-- 2.使用freemarker的標籤引入國際化信息,code爲Bundle文件中配置的key -->
<th><@spring.message code='user.username'/></th>
<th><@spring.message code='user.nick'/></th>
<th><@spring.message code='user.email'/></th>
<th><@spring.message code='user.role'/></th>
<th><@spring.message code='user.status'/></th>
<th width="300"></th>
</tr>
</thead>
...
Spring Boot配置
多語言文案配置
- 在resources文件夾下創建多語言文案的文件夾,我這裏使用languages
- 在這個文件夾下建立業務模塊的Bundle
創建文件,並添加所需國家對應的locale
結果如圖:
spring:
messages:
basename: languages.user // 這裏是多語言文案的Bundle的名字
Configuration
LocaleResolver
去Bundle中找國際化信息是LocaleResolver
根據Locale找對應的文件,web應用默認使用的是AcceptHeaderLocaleResolver
,是根據請求頭中的Accept-Language
來判斷當前的locale,而且不支持setLocale,也就無法在程序中對其locale進行修改,這種方式與我們實際開發運用可能不太符合,可以換成CookieLocaleResolver
.
@Configuration
public class BeanConfig {
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(Locale.CHINA);
resolver.setCookieMaxAge(94608000);
resolver.setCookieName("servicelanguage");
return resolver;
}
}
CookieLocaleResolver
對於我們這裏介紹的功能,與AcceptHeaderLocaleResolver
有兩點不同
- 它是從request的attribute中獲取locale信息
- 支持修改locale
這樣我們就可以根據前臺傳過來的參數動態修改locale,可以在使用的方法中對request的對應attribute進行修改,但是這樣還是太麻煩,每個需要國際化的方法都要加相應的邏輯,於是想到加一個攔截器,批量處理。不過spring已經給了我們解決的方案,提供了對應的攔截器:LocaleChangeInterceptor
LocaleChangeInterceptor
可以看到,在preHandle方法中,會從request參數
(paramName
)中獲取locale的值,再使用localeResolver進行setLocale
,所以我們只要添加一個攔截器即可,並自定義參數名
@Configuration
// 一般這裏可以使用EnableWebMvc,但是會覆蓋默認配置,所以改爲下面import方式,並重寫addInterceptors方法
@Import(WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.class)
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
// 前臺國際化參數名
localeChangeInterceptor.setParamName("lang");
// 攔截的controller
registry.addInterceptor(localeChangeInterceptor).addPathPatterns("/lang/*");
}
}
Controller
/**
* @author future
* @date 2019-12-01 18:40
*/
@Controller
@RequestMapping("lang")
@Slf4j
public class LanguageController {
@RequestMapping("show_local.html")
public String user_local(HttpServletRequest request, ModelMap modelMap) {
PageVO page = new PageVO();
,// 以下是從json文件讀取的數據,這裏沒有做國際化,只有文案做了國際化 page.setContent(JsonUtil.readJsonFile("static/config/userList.json"));
modelMap.addAttribute("page", page);
return "/lang/show_local";
}