【Spring Boot自學筆記二】國際化

所謂國際化,即讓頁面自動根據不同的國家地區顯示對應的語言,好處不必多說。

Spring boot爲我們實現國際化提供了非常方便的方法,我們不再需要自行配置xml,這些配置spring boot已經幫我們自動實現。


前期準備

實現登錄界面

我們先來繪製一個簡單的登錄頁面:

筆者使用bootstrap4做了一些美化,具體美化方法不是重點,本文不再提。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Hello Spring Boot</title>
  <link th:href="@{/webjars/bootstrap/4.4.1-1/css/bootstrap.css}" rel="stylesheet">
</head>
<body>
<section class="text-center">
  <form action="/login" method="post">
    <h2 class="display-4">Login</h2>
    <label>
      <input class="form-control" name="username" type="text" placeholder="Username" th:placeholder="#{index.username}">
    </label>
    <br>
    <label>
      <input class="form-control" name="password" type="text" placeholder="Password" th:placeholder="#{index.password}">
    </label>
    <br>
    <input class="btn btn-primary" type="submit" value="Sign In">
  </form>
</section>
<hr>
</body>
</html>

頁面美化

thymeleaf片段創建

接下來我們再繪製一個導航欄和頁腳,此處純粹美觀需要,可以略過。

在templates中創建一個common.html,輸入以下內容,此處用到thymeleaf的部分標籤:

  • th:fragment: 表示這塊內容是一個片段,可以在其它頁面中被引用,具體引用方法請往下看
  • @{}: 引用超鏈接表達式
  • ${}: 變量表達式
  • #xxx: 使用一個內置對象

thymeleaf找到當前訪問URL的方法

我們來看一下th:href="@{${#httpServletRequest.requestURL}(lang='zh')}"這段話,首先httpServlet是一個內置對象,可以通過requestURL方法得到當前訪問URL,之後用${}表示這是一個變量,再用@{}轉換成超鏈接。

在localhost:8080/index下訪問@{${#httpServletRequest.requestURL}(lang='zh')}相當於訪問localhost:8080/index?lang=zh,相當於給網頁發送了一個帶有參數lang請求,至於請求如何處理我們之後再解決。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset=" UTF-8">
  <title>Common</title>
</head>
<body>
<nav class="navbar navbar-expand navbar-light" th:fragment="headNav">
  <div class="container">
    <a href="/index" class="navbar-brand">Koorye's User Management System</a>
    <ul class="navbar-nav">
      <li class="nav-item"><a href="#" class="nav-link">View User</a></li>
      <li class="nav-item"><a href="#" class="nav-link">About Us</a></li>
    </ul>
  </div>
</nav>

<footer class="text-center" th:fragment="languageOption">
  <a th:href="@{${#httpServletRequest.requestURL}(lang='zh')}">中文</a>
  <a th:href="@{${#httpServletRequest.requestURL}(lang='en')}">English</a>
  <br>
  <a class="text-muted" th:href="@{${#httpServletRequest.requestURL}}">Copyright © 2020 Koorye All Right Reserved.</a>
</footer>
</body>
</html>

thymeleaf片段引用

接下來我們要在主頁中引入導航欄和頁腳,使用th:replace就可以把當前標籤替換成選用的內容,同時thymeleaf還有th:insertth:include方法:

  • th:replace: 替換當前標籤爲選用的內容
  • th:insert: 在當前標籤中添加選用的內容
  • th:include: 保留當前標籤,並把標籤中的內容替換成選用的標籤裏的內容

具體使用,我們在主頁加入以下內容:

  • ~{}片段表達式: common::headNav表示。templates/common.html中的headNav片段,中間用::連接,spring boot會自動爲common拼串加上前後綴,我們之前已經使用th:fragment爲片段命名
...
<nav th:replace="~{common::headNav}"></nav>
...
<footer th:replace="~{common::languageOption}"></footer>
...

效果如下,使用bootstrap4美化之後是不是很漂亮呢?此處的中文/English點擊後還沒有作用,下文再進行完善:
在這裏插入圖片描述


根據瀏覽器語言自動實現國際化

配置國際化文件

在spring boot中,要實現國際化,唯一需要我們做的就是編寫國際化內容的配置文件:

我們在resources目錄中創建i18n目錄,並在目錄中創建lang.properties、lang_en.properties、lang_zh.properties,分別對應默認、英文和中文。

intellij idea提供了非常方便的國際化編輯視圖,我們可以在這個視圖內同時編寫三個配置文件:

在這裏插入圖片描述
注意一下登錄頁面需要什麼國際化內容,我們爲每個內容都創建對應配置:

  • 標題index.title
  • 導航欄標籤common.headNav.label
  • 導航欄鏈接common.headNav.view/common.headNav.aboutUs
  • 登錄窗口標題index.login

    爲每個內容都寫好默認、英文、中文的內容之後,如果要應用,我們還有兩步要做。

修改application.properties

在application.properties中加入一句話,指定國際化的默認配置文件,這裏不加會亂碼哦:

spring.messages.basename=i18n/lang

修改html

在html中使用thymeleaf的th:text標籤(如果是按鈕則用th:value)替換原來的內容,一個簡單的例子:

<title th:text="#{index.title}">Hello Spring Boot</title>

th:text="#{index.title}": #{}是消息表達式,通常用於聲明文本內容,我們在這裏聲明文本內容是配置文件中的index.tile項。

我們依次修改common.html和index.html中的所有標籤,此時thymeleaf就會根據瀏覽器的語言偏好選項自動匹配內容啦!

效果如下:

語言偏好:中文

在這裏插入圖片描述

語言偏好:英文

在這裏插入圖片描述


根據點擊語言選項切換

現在網頁已經可以自動根據瀏覽器的語言偏好選擇語言了,但是我們提供的語言選項點擊後還沒有作用。

我們先來看一下之前提到的內容,點擊中文按鈕,網頁會跳轉到當前URL+/?lang=zh。

在這個例子中,點擊中文,網頁會跳轉到localhost:8080/index/?lang=zh;點擊’English`,則是http://localhost:8080/?lang=en

我們接下來就要根據請求中的parameter參數實現語言切換。

在java包中新建component包,新建一個MyLocaleResolver類,使用LocaleResolver接口,並重寫resolveLocale方法。

我們注意到,resolveLocale方法有一個request參數,這意味着我們可以通過getParameter方法獲取請求中的參數lang。

接下來,我們要做一個if判斷,如果請求中沒有lang參數,我們直接返回瀏覽器請求頭中的語言偏好return request.getLocale(),如果有內容,我們還需要做以下處理。

考慮到語言偏好有兩種格式,一種是語言(如en),一種是語言+國家/地區(如en_US),所以我們這裏先對lang作切割。

如果切割後數組長度爲1,則意味着沒有國家信息,使用return new Locale(lang)直接返回請求參數;如果有國家信息,則使用return new Locale(temp[0],temp[1])返回語言+國家信息:

package org.koorye.hellospringboot.component;

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) {
    //獲取lang參數中的內容
    String lang = request.getParameter("lang");
    
    if (!StringUtils.isEmpty(lang)) {
      //請求中有lang參數,分割語言和國家
      String[] temp = lang.split("_");
      if (temp.length == 1)
        //沒有國家信息,直接返回lang
        return new Locale(lang);
      else
        //有國家信息,組合語言和國家後返回
        return new Locale(temp[0], temp[1]);
    } else {
      //請求中沒有lang參數,返回瀏覽器請求頭的語言偏好
      return request.getLocale();
    }
  }

  @Override
  public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

  }
}

做完這些後還不夠,我們必須把解析器加入到spring boot項目中才行。

在config包中的MVCconfig類中加入(這是筆者在自學筆記一中創建的類,如果沒有也可以自行創建):

只有使用@Bean註解,這個類纔會作爲對象被加入到項目中:

  @Bean
  public LocaleResolver localeResolver() {
    return new MyLocaleResolver();
  }

測試一下,運行成功!

點擊中文
在這裏插入圖片描述
點擊English:
在這裏插入圖片描述
完整項目路徑:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章