所謂國際化,即讓頁面自動根據不同的國家地區顯示對應的語言,好處不必多說。
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:insert
和th: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
:
完整項目路徑: