專案中i18n之實現
i18n全名internationalization,因為中間的字母有18個,於是就用i18n來稱呼它。所謂的i18n就是根據不同的語系會有不同的Message回傳,比如說臺灣人在登入失敗時會出現「登入失敗」,美國人在登入時會出現「Login Fail」,這種因應不同地區的使用者來客製化訊息的工作,就是i18n。
涉及到的基本知識
ResourceBundle
想要做到i18n,最重要的就是地區(Locale)的資料,地區資料有兩個部分組成,分別是語言編碼ISO 639加上區域編碼ISO3166,比如說
- en_US:英文_美國
- en-AU:英文_澳洲
- en-HK :英文_香港
等等的,詳細資訊可以查看http://www.i18nguy.com/unicode/language-identifiers.html
而在Java中,想要實現這樣的功能就會涉及到ResouceBundle
這個類可以用來將程式中的文本,與程式碼分離出來,而不是寫死在程式中,具體可以來看下面的Code。
Java中如何實現i18n
首先先開一個新的Java Maven專案,並在resources的資料夾底下建立兩個檔案
- messages_en_US.properties
- messages_zh_TW.properties
再來到我們的Main方法中,先創建出一個Locale物件
|
|
可以看出是Language跟Country參數
接著創造ResourceBundle物件,其中messages就是我們properties檔案的base name,讓程式知道哪些properties是i18n的文本
|
|
接著我們可以用getString 的方式來取得properties中的值
只要改變Locale的參數,我們就可以去調整打印出來的內容,比如說現在將Locale改成en_US
這樣就是最基礎的,在Java中實現i18n的方法
在SpringBoot中如何實現i18n(基礎)
首先先創造一個SpringBoot專案,接著到application.yml中配置一些基礎資訊
|
|
其中basename就和上面的Java Basename一樣,都是在指定我們的i18配置檔是放在什麼地方,以這個basename為例,就代表放在resources/i18n底下
設置好後,就到resources/i18n資料夾中,配置i18n相關的檔案
[{0}]代表的是格式化訊息的占位符
然後配置一個controller,並加入MessageSource的Bean
MessageSource
是 Spring Framework 提供的一個介面,用於支援應用程式的國際化(Internationalization)和本地化(Localization)。它提供了一種在應用程式中輕鬆管理文本訊息的機制,以便根據使用者的語言和地區首選項來提供相應的文本訊息。
MessageSource
介面的主要功能包括:
- 文本訊息檢索:
MessageSource
允許您在應用程式中定義和存儲文本訊息,通常以鍵值對的形式。這些文本訊息可以是應用程式中的各種提示、標籤、錯誤訊息等。- 國際化支援: 您可以配置不同語言和地區的訊息,以便根據使用者的首選語言和地區設定來動態選擇合適的訊息。這使得應用程式能夠以多語言和本地化方式呈現訊息。
- 參數替換:
MessageSource
支援將參數插入訊息中,以便將動態值嵌入到訊息中。這對於包含佔位符的訊息非常有用。- 訊息格式化: 您可以定義訊息的格式,以適應不同的訊息類型,如日期、時間、貨幣等。
MessageSource
介面的常見實現是ResourceBundleMessageSource
,它使用 Java 的ResourceBundle
機制來存儲和檢索訊息。但 Spring 也提供其他實現,如ReloadableResourceBundleMessageSource
,允許在不重啟應用程式的情況下重新加載訊息資源。使用
MessageSource
的主要步驟包括:
- 配置
MessageSource
Bean,通常在 Spring 配置文件中或 Java 配置類中完成。- 在應用程式中使用
MessageSource
的getMessage
方法來檢索訊息,指定訊息的鍵和可選參數。- 根據使用者的語言和地區首選項,
MessageSource
會動態地返回適當的訊息。總之,
MessageSource
是 Spring Framework 中的一個重要元件,用於實現國際化和本地化,幫助開發者構建多語言和多地區支援的應用程式,提高使用者體驗。–Generate By ChatGPT
|
|
可以看出MessageSource,依照我們配置的Locale去i18n底下找到對應的文本,並且打印出來。我們可以修改Locale的值來改變打印出來的文本
想當然耳,我們不可能是把i18n的配置寫死,所以可以用 LocaleContextHolder.getLocale()來取得目前使用者的語言來動態注入Locale資料
|
|
這部分動態注入的方式,實際實現可以有很多種方式,比如說Interceptor、Filter作轉換,然後用AOP的方式轉換,都是可以行的方案。