リクエストの詳細 (IP アドレス、ブラウザ情報など) を使用して、Java サーブレットでユーザーの国と言語を自動的に検出する必要があります。ほとんどのユーザー (~90%) に対してこれらの設定を検出することは可能ですか?
2 に答える
言語の検出
正しい言語を検出するのは簡単です。WebブラウザはAcceptLanguageヘッダーを送信する傾向があり、JavaサーブレットAPIは、その内容をロケールオブジェクトに実際に変換するのに非常に便利です。この情報にアクセスしてフォールバックメカニズムを実装するだけです。これを行うには、アプリケーションがサポートするロケールのリストが実際に必要です(サポートされているロケールとデフォルトのロケールを含むある種のプロパティファイルを作成することを考えることができます)。以下の例は、そのような実装を示しています。
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をこの順序で送信します)。その理由は、国によって大幅に異なる言語がいくつかあるためです。たとえば、ブラジルポルトガル語はポルトガル語とは異なり、中国語トラディショナル(台湾、香港)は中国語簡体字(中国、シンガポール)とは異なります。それらの1つにフォールバックするのが適切です。
検出国
この情報が何のために必要かによって、簡単な場合とそうでない場合があります。エンドユーザーのWebブラウザーが正しく構成されている場合、それはエンドユーザーの優先する場所のヒントを提供します-それはロケールの一部になります。ロードするローカライズされたページを決定するためにその情報だけが必要な場合は、おそらくそれが最良のオプションです。もちろん、ロケールオブジェクトが特定でない(国がない)場合は、サポートされている非特定のロケールごとに「デフォルト」の国を割り当てることができます。どちらの場合も、エンドユーザーに国を切り替える手段を提供する必要があります(つまり、「その他の国」コンボボックスを使用)。リストは次のように取得できます。
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プロキシを構成し、実際の場所でWebサイトをだます可能性があることです。また、企業ユーザーは、実際には英国またはアイルランドから接続している米国から接続しているように見える場合があります。いずれにせよ、それはあなたのベストショットです。
以前、GeoLocationについていくつか質問がありましたが、役立つと思います。どうぞ。
リクエスト オブジェクトから getlocale を使用します。