1. 程式人生 > >SpringBoot第十集:國際化與Webjars的應用(2020最新最易懂)

SpringBoot第十集:國際化與Webjars的應用(2020最新最易懂)

SpringBoot第十集:i18n與Webjars的應用(2020最新最易懂)

一,頁面國際化

  i18n(其來源是英文單詞 internationalization的首末字元i和n,18為中間的字元數)是“國際化”的簡稱。除了i18n(支援多種語言),L10n(localization),g11n(globalization),還有m17n(multilingualization)

1,什麼是國際化

  國際化就是可以把頁面中的中文變成英文。根據地區使用語言,及瀏覽器語言使用不同,頁面語言也隨之而變化。例如阿里巴巴官網,Dubbo的官方網站等

2, 如何實現頁面國際化?

A,準備工作

  1. 確保工作空間編碼,和後續新建工程檔案編碼都是UTF-8(支援語言型別最強大,俗稱萬國碼)
  2. 新建SpringBoot工程整合Thymeleaf(一切網頁交給模板引擎Thymeleaf接管),並提供預設模板。(整合參考:SpringBoot第九集整合模板引擎)
    至於頁面模板,自己做一個挺麻煩的,可以參考很多後臺元件或模板,BootStrap,EazyUI,layUI,Sematic UI,Admin,XAdmin,AdminLet, Light Year Admin等(我用過的都說了,你看著辦)
  3. 新增控制器,訪問頁面模板
     1 @Controller
     2 public class AdminController {
     3     
     4     /**
     5      * @return 跳轉去登入
     6      */
     7     @RequestMapping("/login")
     8     public String login() {
     9         return "login";
    10     }
    11     
    12 }

    http://localhost:8080/login

    訪問效果:

    注意不要忘記整合Thymeleaf需要加如約束:
    1 <html  class="x-admin-sm"  xmlns:th="http://www.thymeleaf.org">
  4. 新增國際化配置檔案properties,抽取頁面需要顯示的國際化訊息定義在不同命名的檔案中。
    關於配置檔案的命名格式:基本名稱+“_”+語言簡稱+“_”+國家簡稱.properties  注意嚴格區分大小寫(關於語言簡稱可以在附錄中查閱,列舉了 部分可供參考)
    該案例命名舉例:
    login.properties:這個用於作為預設顯示語言配置(預設訪問頁面時顯示的語言配置)
    login_zh_CN.properties:這個用於當指定使用中文時顯示的語言配置
    login_en_US.properties:這個用於當指定使用英文時顯示的語言配置
    實現:
    a,在src/main/resources目錄下新增i18n目錄,新增三個配置檔案

    (當然不同的開發工具,目錄結構效果和適配使用效果是不一樣的,參考SpringBoot第一集)本次演示使用的工具是Spring Tool  Suite

    b,內容大概,實際情況根據你的情況而定
      key對應value,其中key是自定義的,不一定要新增字首,但是,幾個檔案中key一定要相同。

     1 ###用於預設語言顯示的配置檔案
     2 login.message=管理員登入
     3 login.username=使用者名稱
     4 login.password=密碼
     5 login.submit=請登入
     6 #########################################
     7 ###用於指定英文語言顯示的配置檔案
     8 login.message=Administrator Login
     9 login.username=user name
    10 login.password=password
    11 login.submit=Please Login

    c,對應關係

  5. 修改網頁預設資料區
    按照Thymeleaf語法,修改網頁,將所有文字資訊,替換為properties屬性獲取的方式。
    th:Thymeleaf配置屬性語法,Thymeleaf替換值語法th:text,Thymeleaf取值語法#{..........}。詳情參考博主模板引擎Thymeleaf常用語法。
     1 <div class="login layui-anim layui-anim-up">
     2     <!-- th:text的值會替換標籤對之間的內容 -->
     3     <div class="message" th:text="#{login.message}">x-admin2.0-管理登入</div>
     4     <div id="darkbannerwrap"></div>
     5     
     6     <form method="post" class="layui-form" >
     7         <input name="username" th:placeholder="#{login.username}"  type="text" lay-verify="required" class="layui-input" >
     8         <hr class="hr15">
     9         <input name="password" lay-verify="required" th:placeholder="#{login.password}"  type="password" class="layui-input">
    10         <hr class="hr15">
    11         <input th:value="#{login.submit}" lay-submit lay-filter="login" style="width:100%;" type="submit">
    12         <hr class="hr20" >
    13     </form>
    14 </div>

     

B,實現步驟

  1. 修改yml核心配置檔案
     1 spring:     
     2   # 國際化配置        
     3   messages:
     4     # 國際化的檔案的儲存在src\main\resources 資料夾下的什麼位置。注意這是個相對位置
     5     basename: i18n/login
     6     # 表示 messages 檔案的快取失效時間,如果不配置則快取一直有效
     7     cache-duration: 3600
     8     # 配置編碼
     9     encoding: UTF-8
    10     # 如果找不到語言,是不是返回伺服器系統語言。
    11     fallback-to-system-locale: true
  2. 修改頁面前端提交切換引數
    th:是Thymeleaf屬性設定語法。連結語法@{...uri..}。引數語法(key=value&key=value....)詳情參考博主模板引擎Thymeleaf常用語法。
    1 <a th:href="@{login(language=zh_CH)}">簡體中文</a>
    2 <a th:href="@{login(language=en_US)}">English</a>
  3. 編寫自定義語言資訊解析器
    編寫普通類實現介面LocaleResolver,仿SpringBoot預設語言解析器實現(至於為什麼,可以參考附錄SpringBoot國際化原始碼解析)
     1 public class LocaleMessageResolver implements LocaleResolver{
     2     /**
     3      * 使用者可以使用request,根據指定的方式獲取一個Locale,如果沒有獲取到,則使用使用者指定的預設的Locale
     4      */
     5     @Override
     6     public Locale resolveLocale(HttpServletRequest request) {
     7         // 獲取請求資料(切換語言傳遞的引數)
     8         String language = request.getParameter("language");
     9         System.out.println("測試獲取的語言環境引數:"+language);
    10         // 獲取Java虛擬機器此的預設區域語言環境
    11         Locale defaultLocale = Locale.getDefault();
    12         // 判斷頁面是否選擇切換了語言
    13         if (!StringUtil.isEmpty(language)) {// 如果不為null
    14             // 選擇了切換語言環境,將語言環境,根據下劃線拆分
    15             String[] split = language.split("_");// zh  CH
    16             // 建立新的語言環境,並替換預設語言環境(引數一:語言,引數二:國家,詳情參考附錄或JDK-API)
    17             defaultLocale = new Locale(split[0], split[1]);
    18         }
    19         // 返回給頁面的語言環境(要麼系統預設,要麼已經選定的)
    20         return defaultLocale;
    21     }
    22     
    23     /**
    24      * 用於實現Locale的切換。及響應(SpringBoot整合無需這個處理方法)
    25      */
    26     @Override
    27     public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {}
    28 
    29 }
  4. 將自定義加如到Spring IOC
    如果不將自定義的語言解析器放入到Spring容器中,那麼國際化就是無效的!!!
     1 @Configuration    // <beans>
     2 public class LocaleConfig {
     3     /**
     4      * 說明:注入語言解析器時,方法名必須交localeResolver
     5      */
     6     @Bean    // 注入bean
     7     public LocaleMessageResolver localeResolver() {
     8         return new LocaleMessageResolver();
     9     }
    10     
    11 }
  5. 重啟SpringBoot工程,訪問測試
     

二.SpringBoot整合WebJars

  通常對於web開發而言,像jscssimages等靜態資源版本管理是比較混亂的,比如JqueryBootstrapVue.js可能各個前端框架所依賴的自個元件的版本都不盡相同,一不注意就可能引起不同版本的衝突問題。WebJars是將web前端資源(如jQuery & Bootstrap & VUE 等)打成jar包檔案。藉助版本管理工具(Maven、gradle等)進行版本管理,保證這些Web資源版本唯一性。避免了檔案混亂、版本不一致等問題。

開始使用前,我們看下Jquerywebjars,藉此來了解下webjars包的目錄結構。

 

如上圖,可以看到資原始檔地址:META-INF/resources/webjars/jquery/3.5.1/jquery.js

使用方式

 

1.修改pom檔案引入webjars依賴。

  例如:當前引入JQuery測試(注意,雖然已經講過熱部署,但新增依賴依然可能需要重啟服務)。查詢更多依賴

1 <dependency>
2     <groupId>org.webjars</groupId>
3     <artifactId>jquery</artifactId>
4     <version>3.5.1</version>
5 </dependency>

2.頁面引入JQueyr核心檔案測試

  webjars檔案如何引入呢?參考SpringBoot第八集靜態資源地址原始碼解析。

1 <script src="webjars/jquery/3.5.1/jquery.js" type="text/javascript"  charset="utf-8"></script>
2 <script type="text/javascript">
3     $(function(){
4         alert("測試webjars是否引入JQuery可用....");
5     });
6 </script>

  當訪問:webjars/jquery/3.5.1/jquery.js 時,實際載入地址:META-INF/resources/webjars/jquery/3.5.1/jquery.js(資源原地址)

3.webjars應用擴充套件

  當前狀態:頁面引入依賴檔案時,訪問路徑地址加上版本號,總的來說一切都很正常!但時,一旦pom依賴引入的webjars版本更新了,我們就被迫必須更新前臺程式碼。即當前的狀態是,前端硬編碼,不便於靈活使用和更新。所以官方提供了一個webjars-locator包,就是來解決此問題的。

  1. 在maven倉庫搜尋依賴,並引入到當前專案下
    1 <!-- webjars優化版更新本問題 -->
    2 <dependency>
    3     <groupId>org.webjars</groupId>
    4     <artifactId>webjars-locator</artifactId>
    5     <version>0.40</version>
    6 </dependency>
  2. 修改頁面引入路徑問題
    將頁面引入路徑版本號去除,此後,即使pom依賴更新版本,頁面也無需更改了。(當然除非官方有特大改動,名字包名都更新了)
    <script src="webjars/jquery/jquery.js" type="text/javascript"  charset="utf-8"></script>
  3. 頁面測試訪問

  

 

 

附錄

1.國際化配置檔案語言命名

格式說明(嚴格區分大小寫):語言_國家
命名下劃線之前是:語言簡稱
命名下劃線之後是:國家簡稱

語言簡稱
簡體中文(中國) zh_CN
繁體中文(中國臺灣) zh_TW
繁體中文(中國香港) zh_HK
英語(中國香港) en_HK
英語(美國) en_US
英語(英國) en_GB
英語(全球) en_WW
英語(加拿大) en_CA
英語(澳大利亞) en_AU
英語(愛爾蘭) en_IE
英語(芬蘭) en_FI
芬蘭語(芬蘭) fi_FI
英語(丹麥) en_DK
丹麥語(丹麥) da_DK
英語(以色列) en_IL
希伯來語(以色列) he_IL
英語(南非) en_ZA
英語(印度) en_IN
英語(挪威) en_NO
英語(新加坡) en_SG
英語(紐西蘭) en_NZ
英語(印度尼西亞) en_ID
英語(菲律賓) en_PH
英語(泰國) en_TH
英語(馬來西亞) en_MY
英語(阿拉伯) en_XA
韓文(韓國) ko_KR
日語(日本) ja_JP
荷蘭語(荷蘭) nl_NL
荷蘭語(比利時) nl_BE
葡萄牙語(葡萄牙) pt_PT
葡萄牙語(巴西) pt_BR
法語(法國) fr_FR
法語(盧森堡) fr_LU
法語(瑞士) fr_CH
法語(比利時) fr_BE
法語(加拿大) fr_CA
西班牙語(拉丁美洲) es_LA
西班牙語(西班牙) es_ES
西班牙語(阿根廷) es_AR
西班牙語(美國) es_US
西班牙語(墨西哥) es_MX
西班牙語(哥倫比亞) es_CO
西班牙語(波多黎各) es_PR
德語(德國) de_DE
德語(奧地利) de_AT
德語(瑞士) de_CH
俄語(俄羅斯) ru_RU
義大利語(義大利) it_IT
希臘語(希臘) el_GR
挪威語(挪威) no_NO
匈牙利語(匈牙利) hu_HU
土耳其語(土耳其) tr_TR
捷克語(捷克共和國) cs_CZ
斯洛維尼亞語 sl_SL
波蘭語(波蘭) pl_PL
瑞典語(瑞典) sv_SE
西班牙語(智利) es_CL

2.SpringBoot國際化原始碼解析

  springboot國際化的時候,是通過interface LocaleResolver 介面的實現類的bean來確定是哪種語言的。這個介面有2個方法: 1、resolveLocale 用來獲取當前語言環境。 2、setLocale 修改語言環境。(針對Cookie、Session這種有狀態的請求。)

  LocaleResolver的實現類只有4個:

  • AcceptHeaderLocaleResolver(主要解析看這個原始碼)
  • CookieLocaleResolver
  • FixedLocaleResolver
  • SessionLocaleResolver 預設使用AcceptHeaderLocaleResolver實現。
 1 public class AcceptHeaderLocaleResolver implements LocaleResolver {
 2     /**略其他原始碼
 3      * 語言解方法
 4      */
 5     @Override
 6     public Locale resolveLocale(HttpServletRequest request) {
 7         // 每次請求的時候,獲取http的名字叫Accept-Language的header引數,當Accept-Language==null時,使用系統預設Locale;
 8         Locale defaultLocale = getDefaultLocale();
 9         if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
10             return defaultLocale;
11         }
12         // 從當前請求中獲取Locale
13         Locale requestLocale = request.getLocale();
14         // 從配置中獲取支援的Locale集合
15         List<Locale> supportedLocales = getSupportedLocales();
16         // Locale集合為null或者Locale集合中包括請求語言,則直接使用客戶請求Locale
17         if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {
18             return requestLocale;
19         }
20         // 找到設定的Locale集合中是否有請求的Locale
21         Locale supportedLocale = findSupportedLocale(request, supportedLocales);
22         if (supportedLocale != null) {
23             return supportedLocale;
24         }
25         return (defaultLocale != null ? defaultLocale : requestLocale);
26     }
27     // 略其他原始碼
28 }

  總結:AcceptHeaderLocaleResolver實現了國際化解析器介面LocaleResolver,當每次請求發出後,都會執行resolveLocale方法,並通過獲取請求頭"Accept-Language"來判斷使用者是否使用國際化語言切換,沒有選擇切換語言,則直接使用預設語言,當有切換並定義國際化語言時,直接返回指定切換的語言。  

&n