Як інтернаціоналізувати веб-програму Java?


81

Я дізнався від Google, що інтернаціоналізація - це процес, за допомогою якого я можу створити свій веб-додаток на всіх мовах. Я хочу зрозуміти Unicode для процесу інтернаціоналізації, тому я дізнався про Unicode тут і там .

Я можу зрозуміти про Unicode, як набір символів кодується в байтах і знову байтах декодується в коду. Але я не знаю, як рухатися далі. Я хочу навчитися порівнювати рядки, і мені потрібно знати, як реалізувати інтернаціоналізацію у своєму веб-додатку. Будь-які пропозиції, будь ласка? Будь ласка, скеруй мене.

Моя мета:

Моє головне завдання - розробити веб-додаток для перекладу (з англійської на арабську та навпаки). Я хочу стежити за інтернаціоналізацією. Я хочу запустити свою веб-програму для перекладу у всіх трьох браузерах, а саме FF, Chrome, IE. Як мені цього досягти?

Відповіді:


221

У випадку базового веб-застосування JSP / Servlet, основним підходом було б використання JSTL fmttaglib у поєднанні з пакетами ресурсів . Набори ресурсів містять пари ключ-значення, де ключ є константою, однаковою для всіх мов, і значення різниться залежно від мови. Набори ресурсів - це, як правило, файли властивостей, які завантажує ResourceBundleAPI. Однак це можна налаштувати, щоб ви могли завантажувати пари ключ-значення, наприклад, з бази даних.

Ось приклад, як інтернаціоналізувати форму входу до веб-додатка за допомогою пакетів ресурсів на основі властивостей.


  1. Створіть наступні файли та помістіть їх у якийсь пакет, наприклад com.example.i18n(у випадку з Maven, помістіть їх у структуру пакету всередині src/main/resources).

    text.properties (містить пари ключ-значення мовою за замовчуванням, як правило, англійською)

     login.label.username = Ім'я користувача
     login.label.password = Пароль
     login.button.submit = Увійдіть
     

    text_nl.properties(містить голландські ( nl) пари ключ-значення)

     login.label.username = Gebruikersnaam
     login.label.password = Wachtwoord
     login.button.submit = Вхід
     

    text_es.properties(містить іспанські ( es) пари ключ-значення)

     login.label.username = Кількість користувачів
     login.label.password = Contraseña
     login.button.submit = Прискорювач
     

    Ім'я файлу пакета ресурсів має відповідати наступному шаблону name_ll_CC.properties. _llЧастина повинна бути в нижньому регістрі ISO 693-1 код мови. Це необов’язково і вимагається лише тоді, коли _CCдеталь присутня. Ця _CCчастина повинна мати регістр коду країни ISO 3166-1 Alpha-2 у верхньому регістрі . Він є необов’язковим і часто використовується лише для розрізнення діалектів мов, характерних для окремих країн, таких як американський англійський ( _en_US) та британський англійський ( _en_GB).


  2. Якщо це ще не зроблено, встановіть JSTL. Якщо ви працюєте на контейнері Servlet 2.5 або новішій версії (Tomcat 6.0 і так далі), і ви web.xmlоголосили, що відповідає специфікації Servlet 2.5, тоді просто помістіть jstl-1.2.jar у /WEB-INF/libпапку webapp .


  3. Створіть наступний приклад файлу JSP і помістіть його в папку веб-вмісту.

    login.jsp

     <%@ page pageEncoding="UTF-8" %>
     <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
     <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
     <c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="session" />
     <fmt:setLocale value="${language}" />
     <fmt:setBundle basename="com.example.i18n.text" />
     <!DOCTYPE html>
     <html lang="${language}">
         <head>
             <title>JSP/JSTL i18n demo</title>
         </head>
         <body>
             <form>
                 <select id="language" name="language" onchange="submit()">
                     <option value="en" ${language == 'en' ? 'selected' : ''}>English</option>
                     <option value="nl" ${language == 'nl' ? 'selected' : ''}>Nederlands</option>
                     <option value="es" ${language == 'es' ? 'selected' : ''}>Español</option>
                 </select>
             </form>
             <form method="post">
                 <label for="username"><fmt:message key="login.label.username" />:</label>
                 <input type="text" id="username" name="username">
                 <br>
                 <label for="password"><fmt:message key="login.label.password" />:</label>
                 <input type="password" id="password" name="password">
                 <br>
                 <fmt:message key="login.button.submit" var="buttonValue" />
                 <input type="submit" name="submit" value="${buttonValue}">
             </form>
         </body>
     </html>
    

    <c:set var="language">Управляє поточним мовою. Якщо мова була вказана як параметр запиту (через випадаюче меню), тоді вона буде встановлена. В іншому випадку, якщо мова вже була встановлена ​​в сеансі, тоді дотримуйтесь її. В іншому випадку використовуйте надану користувачем локаль у заголовку запиту.

    <fmt:setLocale>Встановлює стандарт для пакета ресурсів. Важливо, щоб цей рядок стояв перед символом <fmt:setBundle>.

    <fmt:setBundle>Ініціалізує пакет ресурсів його базовим ім'я (тобто повне кваліфіковане ім'я пакета , поки з єдиним ім'ям без _ll_CCспецифікатор).

    У <fmt:message>Витягує значення повідомлень зазначеним розшарування ключа.

    У <html lang="${language}">інформуєте searchbots якої мови сторінки , щоб вона не буде позначена як дубльований контент (таким чином, добре для SEO).

    Випадаюче меню негайно надсилатиметься за допомогою JavaScript, коли буде обрано іншу мову, і сторінка буде оновлена ​​заново вибраною мовою.


Однак потрібно пам’ятати, що файли властивостей за замовчуванням читаються із використанням кодування символів ISO-8859-1. Вам потрібно було б уникнути їх шляхом втечі Unicode. Це можна зробити за допомогою native2ascii.exeінструменту, що постачається в JDK . Дивіться також цей розділ статті, щоб дізнатися більше.

Теоретичною альтернативою може бути постачання пакета з користувацьким Controlзавантаженням цих файлів як UTF-8, але це, на жаль, не підтримується базовим таглібом JSTL fmt. Вам потрібно було б усім цим керувати самостійно за допомогою Filter. Є фреймворки (MVC), які можуть обробляти це більш прозоро, наприклад, JSF, див. Також цю статтю .


2
У цього приємного рішення є одна проблема: локаль, взята із запиту, може бути мовою та країною, як у "en_US", що дасть <html lang = "en_US">, що є недійсним HTML. В якості значення для атрибута lang потрібно використовувати лише мовну частину "en" з локалі.
Torsten Römer

1
Вищезазначений метод для інтернаціоналізації не змінює URL-адресу на основі відображеної мови. Чи є у вас пропозиції щодо оновлення URL-адреси відповідно до мови. Я запитую, тому що для індексації рекомендується, щоб різні мови мали окремі URL-адреси: support.google.com/webmasters/answer/…
theyuv

1
Якщо ви розміщуєте файли мовного ресурсу (файли test.properties та text_en.properties) у корені програми / ресурсів, ви можете встановити fmt: bundle таким чином: <fmt: setBundle basename = "text" />
Бахадір Тасдемір

1
@bahadirT: припускаючи, що "тест" - це друкарська помилка, це правильно. Обов’язково basenameмає представляти базове ім’я без розширення файлу. Не структурувати його в пакеті - лише погана практика.
BalusC

1
@theyuv: User has {0} review{0,choice,0#s|1#|1<s} docs.oracle.com/javase/8/docs/api/java/text/MessageFormat.html
BalusC

26

На додаток до того, що сказав BalusC, ви повинні подбати про спрямованість (оскільки англійська мова пишеться зліва направо, а арабська - навпаки). Найпростіший спосіб - додатиdir атрибут до htmlелемента вашої веб-сторінки JSP та екстерналізувати його, тому значення надходить із файлу властивостей (як і з іншими елементами або атрибутами):

<html dir="${direction}">
...
</html>

Крім того, проблем із стилюванням такої програми є небагато - слід як мінімум уникати абсолютного позиціонування. Якщо ви не можете цього уникнути з якихось причин, ви можете або використовувати різні таблиці стилів для (кожної?) Мови, або робити щось, що є багатослівним , тобто використовувати таблиці для управління макетом. Якщо ви хочете використовувати елементи div, я б запропонував використовувати відносне позиціонування з атрибутами стилю "симетричний" ліворуч і праворуч (обидва мають однакове значення), оскільки саме це змушує спрямованість перемикання працювати.

Детальніше про двонаправлені веб-сайти ви можете знайти тут .


7
Так, справді, це теж слід враховувати.
BalusC

4
<html dir="RTL">АБО <html dir="LTR">. За замовчуванням<html dir="LTR">
Фахім Паркар

2

на основі цього підручника я використовую наступне на GAE - Google App Engine:

Jsp-файл наступним чином:

<%@ page import="java.io.* %>
<% 
  String lang = "fr"; //Assign the correct language either by page or user-selected or browser language etc.
  ResourceBundle RB = ResourceBundle.getBundle("app", new Locale(lang));
%>                 

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<head>
</head>
<body>
  <p>      
    <%= RB.getString("greeting") %>
  </p>
</body>

І додавання файлів з іменами: app.properties(за замовчуванням) та app_fr.properties(і так далі для кожної мови). Кожен із цих файлів повинен містити потрібні вам рядки: key: value_in_language, наприклад, app_fr.propertiesмістить:

greeting=Bonjour!

app.properties містить:

greeting=Hello!

Це все

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.