2011-05-13 90 views

回答

12

檢測語言

檢測正確的語言是很容易。 Web瀏覽器傾向於發送AcceptLanguage頭文件,而Java Servlet API實際上很容易將其內容轉換爲Locale對象。您只需訪問這些信息並實施回退機制即可。要做到這一點,您實際上需要應用程序支持的語言環境列表(您可以考慮創建某種類型的包含受支持的語言環境以及默認語言環境的屬性文件)。下面的示例顯示了這樣實現:

public class LousyServlet extends HttpServlet { 
    private Properties supportedLanguages; 
    private Locale requestLocale = (Locale) supportedLanguages.get("DEFAULT"); 

    public LousyServlet() { 
     supportedLanguages = new Properties(); 
     // Just for demonstration of the concept 
     // you would probably load it from i.e. XML 
     supportedLanguages.put("DEFAULT", Locale.US); 
     // example mapping of "de" to "de_DE" 
     supportedLanguages.put("de-DEFAULT", Locale.GERMANY); 
     supportedLanguages.put("de_AT", new Locale("de", "AT")); 
     supportedLanguages.put("de_CH", new Locale("de", "CH")); 
     supportedLanguages.put("ja_JP", Locale.JAPAN); 
    } 

    @Override 
    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     detectLocale(request); 

     super.doGet(request, response); 
    } 

    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     detectLocale(request); 

     super.doPost(request, response); 
    } 

    private void detectLocale(HttpServletRequest request) { 
     Enumeration locales = request.getLocales(); 
     while (locales.hasMoreElements()) { 
      Locale locale = (Locale) locales.nextElement(); 
      if (supportedLanguages.contains(locale)) { 
       requestLocale = locale; 
       break; 
      } 
     } 
    } 

    public String getLanguage() { 
     // get English name of the language 
     // For native call requestLocale.getDisplayName(requestLocale) 
     return requestLocale.getDisplayLanguage(); 
    } 
} 

你要知道,你需要列出所有的國家給定的語言,因爲它不會回落在這種情況下。這就是原因。本地用戶傾向於使用非特定語言環境(例如,我的Web瀏覽器按此順序發送pl_PL,pl,en_US,en)。原因是,有些語言根據國家而有很大差異,例如巴西葡萄牙語與葡萄牙語不同,中國傳統(臺灣,香港)與中國簡體(中國,新加坡)不同,它不會是適合回落到其中之一。

檢測國家

根據你所需要的這些信息,它可能是也可能不是直接的。如果最終用戶的網絡瀏覽器配置正確,它會給你提示最終用戶的首選位置 - 這將是Locale的一部分。如果您只需要這些信息來決定要加載哪個本地化頁面,那可能是最佳選擇。當然,如果Locale對象不是特定的(無國家),您可能需要爲每個受支持的非特定語言環境分配「默認」國家/地區。在這兩種情況下,您都應該爲最終用戶提供一些切換國家的手段(即通過「其他國家」組合框)。可以這樣獲得的名單:

public String[] getOtherCountries() { 
    Set<String> countries = new HashSet<String>(); 
    Set<Object> keys = supportedLanguages.keySet(); 
    for (Object key : keys) { 
     Locale other = (Locale) supportedLanguages.get(key); 
     if (other != requestLocale) { 
      countries.add(other.getDisplayCountry(requestLocale)); 
     } 
    } 

    return countries.toArray(new String[0]); 
} 

但是,如果你需要用它來限制訪問基於位置的內容,這個問題更難。您可能會考慮檢查IP。你需要準備一些地址類屬於給定國家的數據庫。這些數據可以在互聯網上找到。該解決方案唯一的問題是,用戶可能會配置一個Web代理,並欺騙您的網站在他的真實位置。此外,企業用戶可能會看起來好像他們從美國連接,實際上他們從英國或愛爾蘭連接。無論哪種方式,這是你最好的選擇。

以前有一些關於GeoLocation的問題,我相信你會覺得它有用。 Here you are

+1

AFAIK只有一個servlet實例,所以給定的代碼最終會有問題。 – AndrewBourgeois 2012-05-23 14:16:41

+0

@AndrewBourgeois:我看不到你的觀點。如果你關心性能,我會建議對代碼進行剖析而不是預先優化它。如果您的意思是檢測到的語言環境會出現問題,請注意,每個請求都不相同,並且此代碼會分別關注每個請求***。如果你想在每個會話中處理它,你可能想'getSession()'並保存檢測到的'Locale'對象(儘管爲此,我會使用Filter而不是Servlet,並且老實說我不會自己寫它,但是用Spring代替)。 – 2012-05-23 17:56:59

+2

我只是說你要將Locale保存在一個Servlet的實例變量中,這個Servlet的實例是由多個人的多個請求共享的(對於所有請求都是= 1個Servlet實例)。因此,法國人可以將地點設置爲法語,之後美國人可以將英語放入地點。如果法國用戶的請求尚未完成,那麼他的剩餘請求將有一個Enlgish Locale ... – AndrewBourgeois 2012-05-24 06:11:05

1

從請求對象中使用getlocale。

+0

提供的用戶在發送請求之前未在瀏覽器中更改區域設置。 – sudmong 2011-05-13 07:31:59

+0

請參閱[GettingLocaleInformationfromReques](http://www.java2s.com/Code/Java/Servlets/GetLocaleInformationfromRequest.htm) – sudmong 2011-05-13 07:33:08