Определение локали / языка браузера и генерация вывода - PullRequest
4 голосов
/ 19 февраля 2011

У нас есть приложение Java, которое отображает локализованный текст в сеансе браузера пользователя на основе языковых настроек браузера. Приложение считывает языковые настройки браузера [устанавливается в заголовке, который идет как в запросе к приложению] и подготавливает локализованный текст. Но недавно мы столкнулись с проблемами браузера версии Mozilla 5.0. Обратите внимание, что наш код отлично работает в IE. В качестве примера для языка 'ja' мы ожидаем, что браузер отправит принятый язык как 'ja-JP' [что делает IE] - но, к сожалению, Mozilla (FF) этого не делает - он только отправляет принятый браузером язык как 'ja'. Таким образом, мы участвуем в создании контента на языке по умолчанию.

Так как мы предоставляем исправление для того же самого - в основном что-то вроде сопоставления [код языка с кодом страны-страны], например - 'ja' с 'ja-JP', а затем создаем новую локаль [только если после двухзначного кода языка присутствует в запрос] - мой вопрос для других браузеров, таких как
Хром
Safari
и т.д.
Какие языковые форматы отправляются в заголовках?
Таким образом, массив говорит, как это
ja-JP = ja-JP
ja = ja-JP
и сопоставление языка браузера с кодом страны-страны поможет решить проблему. Но есть ли какое-то конкретное ограничение, которое нам нужно устранить - скажем, есть ли языки, на которых говорят в разных местах, - если да, то как бы мы справились с этим?
Любая другая вещь, на которую мы должны обратить внимание?
Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 19 февраля 2011

Посмотрите на класс java.util.ResourceBundle, в основном метод getBundle(). (Вы можете использовать это или реализовать подобный механизм самостоятельно.)

В принципе, у вас есть иерархия локалей, и всякий раз, когда локаль специально не поддерживается, вы возвращаетесь к родительской локали. В вашем случае "ja_JP" (в нотации Java) имеет родительский языковой стандарт "ja", который, в свою очередь, имеет родительский языковой стандарт "".

Поскольку большинство японских страниц не относятся к Японии, вы обычно выполняете весь перевод на японский язык для ja, и только если для японских пользователей в Японии действует только что-то особенное, дополнительно укажите ja_JP. Тогда у вас также не будет проблем, если какой-то пользователь отправит jp_US, поскольку он использует японский в США.


Если вы хотите использовать механизм Java ResourceBundle только для указания, для каких локалей у нас есть данные, вы можете создать (например) эти (пустые) файлы:

  • MyLocale.properties - соответствует "" Locale
  • MyLocale_de.properties - соответствует локали "de" (немецкий)
  • MyLocale_en.properties - соответствует локали "en" (английский)
  • MyLocale_ja.properties - соответствует локали "ja" (японский)

Тогда в вашей программе вы бы написали

Locale rLocale = request.getLocale();
ResourceBundle bundle = ResourceBundle.getBundle("MyLocale", rLocale);
Locale selectedLocale = bundle.getLocale();

Теперь selectedLocale определенно является одним из "", "de", "en", "jp", независимо от того, какой была локаль rLocale. Например, для «en», «en_GB», «en_US» во всех случаях будет выбрано «en», «ja» и «ja_JP» приведут к «ja», тогда как «de_DE» и «de_AT» будут оба приводят к "de", а "it_IT", "eo" и большинству других локалей приводят к "".


«Правильный путь Java» для этого: Вы не спросите свой пакет о его Locale, а просто используете его как ResourceBundle, беря из него локализованные ресурсы. Итак, когда вам нужен текст, вы делаете

 String text = bundle.getText("greeting.hello");

и затем выведите текст. Иногда вы должны использовать MessageFormat для форматирования текста со вставленными значениями (или Formatter). (Тогда ваши файлы свойств, конечно, не будут пустыми, но будут содержать такие строки:

 greeting.hello = Hello World!

(в английском файле)

 greeting.hello = Hallo Welt!

(в немецком файле)


Обратите внимание, что часто браузер отправляет не только один код локали, но и список предпочтительных. Таким образом, на самом деле вы должны выполнить этот «поиск по пакетам» для каждого из этих кодов и взять первый, который действительно возвращает что-то отличное от «», и возвращаться к «» только тогда, когда не найдено ни одного запрошенного языка. (Например, мой браузер отправляет «eo», «de_DE», «de», «en». Поскольку большинство веб-сайтов не поддерживают эсперанто, они обращаются к немецкому (если доступно и выбор реализован правильно), или к язык по умолчанию (если они смотрят только на первую запись)).

0 голосов
/ 19 декабря 2014

Вы можете получить список локалей из класса Java - Locale.Вызывая метод, getAvailableLocale ().

http://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#getAvailableLocales--

0 голосов
/ 19 февраля 2011

http://www.tutorialspoint.com/jsp/jsp_internationalization.htm

и более подробная информация о запросе: http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/Servlet-Tutorial-Request-Headers.html

            package hall;

            import java.io.*;
            import javax.servlet.*;
            import javax.servlet.http.*;
            import java.util.*;

            /** Shows all the request headers sent on this
             *  particular request.
             *  <P>
             *  Part of tutorial on servlets and JSP that appears at
             *  http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/
             *  1999 Marty Hall; may be freely used or adapted.
             */

            public class ShowRequestHeaders extends HttpServlet {
              public void doGet(HttpServletRequest request,
                        HttpServletResponse response)
                  throws ServletException, IOException {
                response.setContentType("text/html");
                PrintWriter out = response.getWriter();
                String title = "Servlet Example: Showing Request Headers";
                out.println(ServletUtilities.headWithTitle(title) +
                    "<BODY BGCOLOR=\"#FDF5E6\">\n" +
                    "<H1 ALIGN=CENTER>" + title + "</H1>\n" +
                    "<B>Request Method: </B>" +
                    request.getMethod() + "<BR>\n" +
                    "<B>Request URI: </B>" +
                    request.getRequestURI() + "<BR>\n" +
                    "<B>Request Protocol: </B>" +
                    request.getProtocol() + "<BR><BR>\n" +
                    "<TABLE BORDER=1 ALIGN=CENTER>\n" +
                    "<TR BGCOLOR=\"#FFAD00\">\n" +
                    "<TH>Header Name<TH>Header Value");
                Enumeration headerNames = request.getHeaderNames();
                while(headerNames.hasMoreElements()) {
                  String headerName = (String)headerNames.nextElement();
                  out.println("<TR><TD>" + headerName);
                  out.println("    <TD>" + request.getHeader(headerName));
                }
                out.println("</TABLE>\n</BODY></HTML>");
              }

              public void doPost(HttpServletRequest request,
                         HttpServletResponse response)
                  throws ServletException, IOException {
                doGet(request, response);
              }
            }
...