Servlet中自动为用户选择国家和语言

Servlet中自动为用户选择国家和语言

本文介绍了在Java Servlet中自动为用户选择国家和语言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用请求详细信息(IP地址,浏览器信息等)在Java Servlet中自动检测用户国家和语言.是否有可能为大多数用户(约90%)检测到这些设置?

I have to detect user country and language automatically in Java Servlet using request details (IP address, browser information etc.). Is it possible to detect these settings for the most of users (~90%)?

推荐答案

检测语言

检测正确的语言很容易. Web浏览器倾向于发送AcceptLanguage标头,而Java Servlet API非常适合将其内容实际转换为Locale对象.您所要做的只是访问此信息并实施回退机制.为此,您实际上需要应用程序要支持的语言环境列表(您可以考虑创建某种类型的属性文件,其中将包含受支持的语言环境以及默认语言环境).下面的示例显示了这样的实现:

Detecting the correct language is easy. Web browsers tend to send AcceptLanguage header and Java Servlet API is so nice to actually convert it contents to Locale object(s). All you would have to do, is just access this information and implement fall-back mechanism. To do that you actually need a list of Locales your application is going to support (you could think of creating some sort of Properties file that would contain supported locales along with default one). Example below shows such implementation:

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();
    }
}

请记住,您需要列出给定语言的所有国家/地区,因为在这种情况下,它不会退一步.这是出于原因.本地用户倾向于使用非特定的Locale(例如,我的Web浏览器以该顺序发送pl_PL,pl,en_US,en).原因是,有些语言会因国家/地区而有很大差异,例如巴西葡萄牙语与葡萄牙语有所不同,而繁体中文(台湾,香港)与简体中文(中国,新加坡)也不同,因此不会适合回落到其中之一.

Mind you, that you would need to list all the countries for given language, as it won't fall back in this case. That is for the reason. Local users tend to have non-specific Locale either way (for example my web browser sends pl_PL, pl, en_US, en in that order). And the reason is, there are some languages that differs substantially depending on the country, for example Brazilian Portuguese is different than Portuguese and Chinese Traditional (Taiwan, Hong Kong) is different than Chinese Simplified (China, Singapore) and it won't be appropriate to fall back to one of them.

检测国家/地区

取决于您需要此信息的用途,它可能很简单,也可能不是很简单.如果最终用户的Web浏览器配置正确,它将提示您最终用户的首选位置-这将是Locale的一部分.如果您只需要该信息来决定要加载哪个本地化页面,那可能是最好的选择.当然,如果Locale对象不是特定的(无国家/地区),则可能要为每个受支持的非特定Locale分配默认"国家/地区.在这两种情况下,您都应为最终用户提供一些切换国家/地区的方法(即通过其他国家/地区"组合框).可以这样获得列表:

Depending on what you need this information for, it might or might not be straightforward. If end user's web browser is configured correctly, it will give you the hint of end user's preferred location - that would be the part of Locale. If you only need that information to decide on which localized page to load, that would be probably the best option. Of course if Locale object is not specific (country-less) you may want to assign "default" country for each supported non-specific Locale. In both cases, you should provide end user with some means of switching country (i.e. through "Other countries" combo box). The list could be obtained like this:

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上找到此数据.该解决方案的唯一问题是,用户可以配置Web代理并在其实际位置上欺骗您的网站.同样,公司用户可能看起来好像他们是从美国连接的,而实际上是从英国或爱尔兰连接的.无论哪种方式,这都是您的最佳选择.

If however, you need this to restrict the access to the contents based on location, the problem is harder. You may think of checking the IP. You would need to prepare some Database with address classes that belongs to given country. This data could be found on the Internet. The only problem with that solution is, user may configure a web proxy and fool your web site on his real location. Also, corporate users might appear as if they connect from USA where in fact they connect from UK or Ireland. Either way, it is your best shot.

之前,地理位置上存在一些问题,我相信您可能会发现它很有用. 您在这里.

There was some question on GeoLocation before and I believe you may find it useful. Here you are.

这篇关于在Java Servlet中自动为用户选择国家和语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 03:17