Автоматический выбор страны и языка для пользователя в сервлете Java - PullRequest
7 голосов
/ 13 мая 2011

Я должен автоматически определять страну и язык пользователя в сервлете Java, используя данные запроса (IP-адрес, информацию о браузере и т. Д.).Можно ли обнаружить эти настройки для большинства пользователей (~ 90%)?

Ответы [ 2 ]

12 голосов
/ 14 мая 2011

Обнаружение языка

Легко определить правильный язык. Веб-браузеры, как правило, отправляют заголовок 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 в таком порядке). И причина в том, что есть некоторые языки, которые существенно различаются в зависимости от страны, например, бразильский португальский отличается от португальского, а китайский традиционный (Тайвань, Гонконг) отличается от упрощенного китайского (Китай, Сингапур) и не будет уместно отступить к одному из них.

Страна обнаружения

В зависимости от того, для чего вам нужна эта информация, она может быть или не быть простой. Если веб-браузер конечного пользователя настроен правильно, он даст вам подсказку о предпочтительном расположении конечного пользователя - это будет частью Locale. Если вам нужна только эта информация, чтобы решить, какую локализованную страницу загрузить, это, вероятно, будет лучшим вариантом. Конечно, если объект 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. Вам необходимо подготовить базу данных с адресными классами, принадлежащими данной стране Эти данные можно найти в Интернете. Единственная проблема, связанная с этим решением, заключается в том, что пользователь может настроить веб-прокси и обмануть ваш веб-сайт в своем реальном местоположении. Кроме того, корпоративные пользователи могут выглядеть так, как будто они подключаются из США, где на самом деле они подключаются из Великобритании или Ирландии. В любом случае, это ваш лучший выстрел.

Ранее был вопрос о геолокации, и я думаю, что вы найдете его полезным. Вот вы .

1 голос
/ 13 мая 2011

использовать getlocale из объекта запроса.

...