我必须使用请求详细信息(IP 地址、浏览器信息等)在 Java Servlet 中自动检测用户国家和语言。是否可以为大多数用户(~90%)检测这些设置?
2 回答
检测语言
检测正确的语言很容易。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();
}
}
请注意,您需要列出给定语言的所有国家/地区,因为在这种情况下它不会退回。这就是原因。无论哪种方式,本地用户都倾向于使用非特定的语言环境(例如,我的网络浏览器按此顺序发送 pl_PL、pl、en_US、en)。原因是,有些语言因国家/地区而异,例如巴西葡萄牙语与葡萄牙语不同,繁体中文(台湾,香港)与简体中文(中国,新加坡)不同,不会是适合退回到其中之一。
检测国家
根据您需要此信息的目的,它可能简单,也可能不简单。如果最终用户的 Web 浏览器配置正确,它将提示您最终用户的首选位置 - 这将是 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。您需要准备一些具有属于给定国家/地区的地址类的数据库。这些数据可以在 Internet 上找到。该解决方案的唯一问题是,用户可能会配置网络代理并在他的真实位置欺骗您的网站。此外,企业用户可能看起来好像是从美国连接的,而实际上他们是从英国或爱尔兰连接的。无论哪种方式,这都是你最好的选择。
之前有一些关于 GeoLocation 的问题,我相信您可能会发现它很有用。你在这里。
从请求对象中使用 getlocale。