首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Locale 解析工具類:跨平台語言標籤標準化處理

     編輯:Java 相關知識

Java 原生 Locale 建構子僅支援固定參數組合,實務上常需從字串(如 zh_CN、en-US、zh_TW_STROKE)動態解析。本文提供一個健壯的 LocaleUtil,相容大小寫、底線/連字號分隔符、三段式 variant,並修正 Apache LocaleUtils 不支援小寫開頭的缺陷。

核心需求

  • 支援 language、language_country、language_country_variant 三種格式。
  • 分隔符同時相容 _ (Java 標準) 與 - (IETF BCP 47)。
  • 大小寫正規化:語言碼小寫、國家碼大寫、variant 大寫。
  • 輸入為空或格式錯誤時回傳預設 Locale.ENGLISH,不拋出異常。

工具類完整程式碼

import java.util.Locale;

public class LocaleUtil {
    private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
    public static final String IETF_SEPARATOR = "-";
    public static final String SEPARATOR = "_";
    private static final String EMPTY = "";

    public static Locale toLocale(String language) {
        if (isBlank(language)) return DEFAULT_LOCALE;
        return langToLocale(language, SEPARATOR);
    }

    public static Locale langToLocale(String lang, String separator) {
        if (isBlank(lang)) return DEFAULT_LOCALE;

        String language = EMPTY, country = EMPTY, variant = EMPTY;
        int i1 = lang.indexOf(separator);
        if (i1 < 0) {
            language = lang;
        } else {
            language = lang.substring(0, i1);
            ++i1;
            int i2 = lang.indexOf(separator, i1);
            if (i2 < 0) {
                country = lang.substring(i1);
            } else {
                country = lang.substring(i1, i2);
                variant = lang.substring(i2 + 1);
            }
        }

        // 正規化
        if (language.length() == 2) language = language.toLowerCase();
        else language = EMPTY;

        if (country.length() == 2) country = country.toUpperCase();
        else country = EMPTY;

        if (variant.length() > 0 && (language.length() == 2 || country.length() == 2)) {
            variant = variant.toUpperCase();
        } else {
            variant = EMPTY;
        }

        return new Locale(language, country, variant);
    }

    private static boolean isBlank(String s) {
        return s == null || s.isEmpty();
    }
}

測試驗證

輸入字串解析結果 (toString)說明
zh_CNzh_CN標準底線分隔
zh-cnzh_CN連字號 + 小寫 → 自動正規化
en_US_POSIXen_US_POSIX三段式 variant 保留
JAVAen非標準語言碼 → 回預設
nullen空值安全

進階應用場景

  • HTTP 請求解析: LocaleUtil.toLocale(request.getHeader("Accept-Language")) 取得首選語系。
  • 配置檔讀取: Spring @Value("${app.locale:zh_TW}") 搭配 LocaleUtil.toLocale() 注入 Bean。
  • 資料庫儲存: 統一存 toString() 格式(zh_TW),讀取時再轉 Locale 物件。

注意事項

  1. Java 7+ 建議直接使用 Locale.forLanguageTag(String)(支援 BCP 47),但仍需自行處理預設值與空值邏輯。
  2. variant 非標準化欄位,僅作為應用層擴充(如 POSIX、STROKE),勿用於核心邏輯分支。
  3. 若需支援 Unicode 擴展(如 u-ca-japanese),請改用 Locale.Builder 或 ICU4J。

將 LocaleUtil 納入專案共用模組,即可一勞永逸解決語系標籤解析的跨平台相容問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved