Table of Contents
ToggleSpring Boot MessageSource
支援多語系訊息顯示,自動設定國際化,能根據不同語言及地區顯示相對應的語言,有助於開發人員通過編寫大量額外代碼來處理各種複雜場景,例如特定於環境的設定、國際化或可設定值,另一種情況是將預設驗證消息修改為更加友好及自定義的訊息, EP 9 增加了設定檔設定及建立了多國語系檔, Spring Message Source 透過單元測試來驗證產出結果。
功能簡介
MessageSource 訊息國際化,根據不同的使用者採用不同的語言、數字格式、日期格式等,當系統被移植到不同的語言及地區時,本身不用做內部工程上的改變或修正,就能正確顯示相對應的訊息。
檔案目錄
./
+- build.gradle
+- src
+- main
| +- resources
| +- application.properties
| +- static
| +- i18n
| | +- messages_en_US.properties
| | +- messages_ja_JP.properties
| | +- messages_zh_CN.properties
| | +- messages_zh_TW.properties
| | +- messages.properties
+- test
| +- org
| +- ruoxue
| +- spring_boot_168
| +- test
| +- junit4
| +- MessageSourceTest.java
Gradle
build.gradle
增加 Spring Boot Starter Test 。
修改完後,點右鍵,Gradle -> Refresh Gradle Project 。
buildscript {
group 'org.ruoxue.spring-boot-168'
version = '0.0.1-SNAPSHOT'
ext {
springBootVersion = '2.1.7.RELEASE'
}
}
dependencies {
testImplementation 'junit:junit:4.12'
testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}"
}
組態設定
application.properties
Spring Boot Message Properties 增加 Messages 設定。
spring.messages.always-use-message-format=false
spring.messages.basename=static/i18n/messages
spring.messages.cache-duration=3600
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=true
spring.messages.use-code-as-default-message=false
語系設定
messages_zh_TW.properties
Message Source Spring 新增檔案,增加訊息內容。
spring-boot-168.contact.name=若雪
spring-boot-168.contact.url=https://www.ruoxue.org
spring-boot-168.contact.email=ruoxueorg@gmail.com
spring-boot-168.contact.content=歡迎與我們聯絡,可以利用信箱或是社團留言的方式,留下訊息。
messages_en_US.properties
Message Source Spring 新增檔案,增加訊息內容。
spring-boot-168.contact.name=Ruoxue
spring-boot-168.contact.url=https://www.ruoxue.org
spring-boot-168.contact.email=ruoxueorg@gmail.com
spring-boot-168.contact.content=Welcome to contact us, you can use the mailbox or community message.
messages_zh_CN.properties
Message Source Spring 新增檔案,增加訊息內容。
spring-boot-168.contact.name=若雪
spring-boot-168.contact.url=https://www.ruoxue.org
spring-boot-168.contact.email=ruoxueorg@gmail.com
spring-boot-168.contact.content=欢迎与我们联络,可以利用信箱或是社团留言的方式,留下讯息。
messages_ja_JP.properties
Message Source Spring 新增檔案,增加訊息內容。
spring-boot-168.contact.name=ルクスエ
spring-boot-168.contact.url=https://www.ruoxue.org
spring-boot-168.contact.email=ruoxueorg@gmail.com
spring-boot-168.contact.content=メールボックスまたはコミュニティメッセージを使用して、お問い合わせください。
messages.properties
當找不到對應語系檔,預設採用此語系,內容同 messages_en_US.properties。
單元測試
MessageSourceTest.java
Message Source Spring 新增單元測試檔案,增加 @RunWith(SpringRunner.class)。
package org.ruoxue.spring_boot_168.test.junit4;
import static org.junit.Assert.assertEquals;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ruoxue.spring_boot_168.Application;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.MessageSource;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class MessageSourceTest {
@Autowired
private MessageSource messageSource;
@Test
public void getMessage_zh_TW() {
String name = messageSource.getMessage("spring-boot-168.contact.name", (Object[]) null,
Locale.TRADITIONAL_CHINESE);
System.out.println("name: " + name);
assertEquals("若雪", name);
String url = messageSource.getMessage("spring-boot-168.contact.url", (Object[]) null,
Locale.TRADITIONAL_CHINESE);
System.out.println("url: " + url);
assertEquals("https://www.ruoxue.org", url);
String email = messageSource.getMessage("spring-boot-168.contact.email", (Object[]) null,
Locale.TRADITIONAL_CHINESE);
System.out.println("email: " + email);
assertEquals("ruoxueorg@gmail.com", email);
String content = messageSource.getMessage("spring-boot-168.contact.content", (Object[]) null,
Locale.TRADITIONAL_CHINESE);
System.out.println("content: " + content);
}
@Test
public void getMessage_en_US() {
String name = messageSource.getMessage("spring-boot-168.contact.name", (Object[]) null, Locale.US);
System.out.println("name: " + name);
assertEquals("Ruoxue", name);
String url = messageSource.getMessage("spring-boot-168.contact.url", (Object[]) null, Locale.US);
System.out.println("url: " + url);
assertEquals("https://www.ruoxue.org", url);
String email = messageSource.getMessage("spring-boot-168.contact.email", (Object[]) null, Locale.US);
System.out.println("email: " + email);
assertEquals("ruoxueorg@gmail.com", email);
String content = messageSource.getMessage("spring-boot-168.contact.content", (Object[]) null, Locale.US);
System.out.println("content: " + content);
}
@Test
public void getMessage_zh_CN() {
String name = messageSource.getMessage("spring-boot-168.contact.name", (Object[]) null,
Locale.SIMPLIFIED_CHINESE);
System.out.println("name: " + name);
assertEquals("若雪", name);
String url = messageSource.getMessage("spring-boot-168.contact.url", (Object[]) null,
Locale.SIMPLIFIED_CHINESE);
System.out.println("url: " + url);
assertEquals("https://www.ruoxue.org", url);
String email = messageSource.getMessage("spring-boot-168.contact.email", (Object[]) null,
Locale.SIMPLIFIED_CHINESE);
System.out.println("email: " + email);
assertEquals("ruoxueorg@gmail.com", email);
String content = messageSource.getMessage("spring-boot-168.contact.content", (Object[]) null,
Locale.SIMPLIFIED_CHINESE);
System.out.println("content: " + content);
}
@Test
public void getMessage_ja_JP() {
String name = messageSource.getMessage("spring-boot-168.contact.name", (Object[]) null, Locale.JAPAN);
System.out.println("name: " + name);
assertEquals("ルクスエ", name);
String url = messageSource.getMessage("spring-boot-168.contact.url", (Object[]) null, Locale.JAPAN);
System.out.println("url: " + url);
assertEquals("https://www.ruoxue.org", url);
String email = messageSource.getMessage("spring-boot-168.contact.email", (Object[]) null, Locale.JAPAN);
System.out.println("email: " + email);
assertEquals("ruoxueorg@gmail.com", email);
String content = messageSource.getMessage("spring-boot-168.contact.content", (Object[]) null, Locale.JAPAN);
System.out.println("content: " + content);
}
}
getMessage_zh_TW
測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console。
name: 若雪
url: https://www.ruoxue.org
email: ruoxueorg@gmail.com
content: 歡迎與我們聯絡,可以利用信箱或是社團留言的方式,留下訊息。
getMessage_en_US
測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console。
name: Ruoxue
url: https://www.ruoxue.org
email: ruoxueorg@gmail.com
content: Welcome to contact us, you can use the mailbox or community message.
getMessage_zh_CN
測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console。
name: 若雪
url: https://www.ruoxue.org
email: ruoxueorg@gmail.com
content: 欢迎与我们联络,可以利用信箱或是社团留言的方式,留下讯息。
getMessage_ja_JP
測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console。
name: ルクスエ
url: https://www.ruoxue.org
email: ruoxueorg@gmail.com
content: メールボックスまたはコミュニティメッセージを使用して、お問い合わせください。
故障排除
缺少 @RunWith
執行 JUnit Test,拋出例外,發生錯誤,stack trace 如下:
java.lang.NullPointerException
at test.MessageSourceTest.getMessage_zh_TW(MessageSourceTest.java:22)
這是因為沒有整合 Spring ,messageSource 無建構成物件,要加上 @RunWith 註解,使其實例化,修改完後,再次執行,就能順利運行。
// 修改前
@SpringBootTest(classes = Application.class)
public class MessageSourceTest {
// 修改後
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class MessageSourceTest {
心得分享
Spring Boot MessageSource 走向國際化,意味著產品有適用於任何地方的潛力,讓所研發的產品能輕易地配合許多不同國家、地區,使用 MessageSource Spring Boot 滿足許多不同客群的語系需求。