Java-Webanwendung i18n

8

Ich habe die (ziemlich schwierige) Aufgabe bekommen, i18n mit der 2.3 Servlet-Spezifikation in eine J2EE-Webanwendung einzuführen. Die Anwendung ist sehr groß und seit über 8 Jahren in der aktiven Entwicklung.

Als solches möchte ich beim ersten Mal die Dinge richtig stellen, damit ich die Zeit, die ich brauche, um JSPs, JavaScript-Dateien, Servlets und wo auch immer zu scrollen, durch hartcodierte Strings durch Werte aus Nachrichtenbündeln zu begrenzen / p>

Hier wird kein Rahmen verwendet. Wie kann ich mich an die Unterstützung von i18n wenden? Beachten Sie, dass ich eine einzelne JSP pro Ansicht haben möchte, die Text aus (a) Eigenschaftendatei (en) und nicht eine andere JSP für jedes unterstützte Gebietsschema lädt.

Ich denke, meine Hauptfrage ist, ob ich das Gebietsschema irgendwo im "Backend" einstellen kann (dh Gebietsschema vom Benutzerprofil beim Login lesen und Wert in der Sitzung speichern) und dann erwarte, dass die JSP-Seiten den Laden korrekt laden können angegebene Zeichenfolge aus der richtigen Eigenschaftendatei (dh aus messages_fr.properties, wenn das Gebietsschema auf Französisch eingestellt ist), im Gegensatz zum Hinzufügen von Logik, um das richtige Gebietsschema in jeder JSP zu finden.

Irgendwelche Ideen, wie ich das angehen kann?

    
NRaf 23.06.2011, 01:41
quelle

3 Antworten

18

Es gibt viele Dinge, die bei der Internationalisierung von Anwendungen beachtet werden müssen:

Gebietsschemaerkennung

Das erste, worüber Sie nachdenken müssen, ist das Locale des Endanwenders zu erkennen. Je nachdem, was Sie unterstützen möchten, kann es leicht oder ein wenig kompliziert sein.

  1. Wie Sie sicherlich wissen, senden Webbrowser die bevorzugte Sprache des Endbenutzers über den Header HTTP Accept-Language. Der Zugriff auf diese Informationen im Servlet kann so einfach sein wie das Aufrufen von request.getLocale() . Wenn Sie nicht vorhaben, einen ausgefallenen Locale-Erkennungs-Workflow zu unterstützen, können Sie sich einfach an diese Methode halten.
  2. Wenn Sie in Ihrer Anwendung Benutzerprofile haben, möchten Sie möglicherweise die bevorzugte Sprache und das bevorzugte Formatierungsgebietsschema hinzufügen. In diesem Fall müssten Sie nach der Anmeldung des Benutzers die Sprache wechseln.
  3. Möglicherweise möchten Sie die URL-basierte Sprachumschaltung unterstützen (z. B. Ссылка oder Ссылка ). Sie müssten gültige Ländereinstellungen basierend auf URL-Informationen festlegen - dies könnte auf verschiedene Arten erfolgen (z. B. URL-Filter).
  4. Vielleicht möchten Sie die Sprachumschaltung unterstützen (Auswahl aus dem Dropdown-Menü oder etwas), aber ich würde es nicht empfehlen (es sei denn, es wird mit Punkt 3 kombiniert).

JSTL Ansatz könnte ausreichen, wenn Sie nur die erste Methode unterstützen möchten oder wenn Sie keine zusätzlichen Abhängigkeiten hinzufügen möchten (wie Spring Framework).

>

Während wir uns im Spring Framework befinden, hat es einige nette Features, die Sie beide zur Erkennung von Locale verwenden können (wie , AcceptHeaderLocaleResolver , SessionLocaleResolver und LocaleChangeInterceptor ) und Strings externalisieren und Nachrichten formatieren (siehe Frühling:Message Tab ).
Spring Framework würde es Ihnen ermöglichen, alle oben genannten Szenarien recht einfach zu implementieren und deshalb bevorzuge ich es.

String-Externalisierung

Das sollte einfach sein, oder? Nun, meistens ist es - verwenden Sie nur passende Tags. Das einzige Problem, dem Sie möglicherweise gegenüberstehen, ist die Externalisierung von clientseitigen (JavaScript-) Texten. Es gibt mehrere mögliche Ansätze, aber lassen Sie mich diese zwei erwähnen:

  1. Lassen Sie jedes JSP-Array mit übersetzten Strings schreiben (mit Message-Tag) und greifen Sie einfach auf dieses Array im Client-Code zu. Dies ist einfacher, aber weniger wartbar - Sie müssten tatsächlich gültige Strings aus gültigen Seiten schreiben (diejenigen, die tatsächlich auf Ihre clientseitigen Skripte verweisen). Ich habe das schon einmal gemacht und glaube mir, das ist nicht etwas, was du in großen Anwendungen machen willst (aber es ist wahrscheinlich die beste Lösung für kleine).
  2. Eine andere Herangehensweise mag im Prinzip hart klingen, aber in der Zukunft ist sie tatsächlich viel einfacher zu handhaben. Die Idee besteht darin, Zeichenfolgen auf der Clientseite zu zentralisieren (verschieben Sie sie in eine gemeinsame JavaScript-Datei). Danach müssen Sie Ihr eigenes Servlet implementieren, das dieses Skript auf Anfrage zurückgibt - der Inhalt sollte übersetzt werden. Sie können JSTL hier nicht verwenden, Sie müssten Strings direkt aus den Ressourcenbündeln abrufen.
    Es ist viel einfacher zu pflegen, weil Sie einen zentralen Punkt haben, um übersetzbare Zeichenfolgen hinzuzufügen.

Verkettungen

Ich hasse es, das zu sagen, aber Verkettungen sind aus Sicht der Lokalisierbarkeit wirklich schmerzhaft. Sie sind sehr verbreitet und die meisten Menschen erkennen es nicht.

Was ist also Verkettung?

Grundsätzlich muss jeder englische Satz in die Zielsprache übersetzt werden. Das Problem ist, dass es oft vorkommt, dass die korrekt übersetzte Nachricht eine andere Wortreihenfolge verwendet als ihr englisches Gegenstück (so wird "Policyka bezpieczeństwa" übersetzt - "Politik" ist "polityka" - die Reihenfolge ist anders).

OK, aber wie hängt es mit der Software zusammen?

In der Webanwendung können Sie Strings wie folgt verketten:

%Vor%

oder wie folgt:

%Vor%

Beide wären problematisch.Im ersten Fall müssten Sie MessageFormat.format() method verwenden und Strings externalisieren, wie zum Beispiel "Security {0}" und "policy" , in letzterem würden Sie den Inhalt des gesamten Absatzes (p tag), einschließlich , externalisieren span-Tag Ich weiß, dass dies für die Übersetzer schmerzhaft ist, aber es gibt wirklich keinen besseren Weg Manchmal müssen Sie dynamischen Inhalt in Ihrem Absatz verwenden - JSTL fmt: format-Tag wird Ihnen auch hier helfen (es funktioniert lime MessageFormat auf der Backend-Seite).

Layouts

In lokalisierten Anwendungen passiert es oft, dass übersetzte Strings viel länger sind als englische. Das Ergebnis könnte sehr hässlich aussehen. Irgendwie müssten Sie Stile reparieren. Es gibt wieder zwei Ansätze:

  1. Beheben Sie Probleme, indem Sie gängige Stile anpassen (und beten Sie, dass andere Sprachen nicht verletzt werden). Dies ist sehr schmerzhaft zu halten.
  2. Implementieren Sie den CSS-Lokalisierungsmechanismus. Der Mechanismus, über den ich spreche, sollte eine standardmäßige sprachunabhängige CSS-Datei und Sprachüberschreibungen bieten. Die Idee ist, die CSS-Datei für jede Sprache zu überschreiben, so dass Sie die Layouts bei Bedarf anpassen können (nur für eine Sprache). Zu diesem Zweck dürfen die CSS-Standarddatei sowie JSP-Seiten neben allen Stildefinitionen !important keyword nicht enthalten. Wenn Sie sie wirklich verwenden müssen, verschieben Sie sie in die sprachbasierte de.css - dies würde anderen Sprachen erlauben, sie zu ändern.

Kulturspezifische Probleme

Vermeiden Sie die Verwendung von Grafiken, Farben und Tönen, die für die westliche Kultur typisch sind. Wenn Sie es wirklich brauchen, geben Sie bitte Lokalisierungsmöglichkeiten an. Vermeiden Sie richtungsabhängige Grafiken (dies wäre ein Problem, wenn Sie versuchen, Arabisch oder Hebräisch zu lokalisieren). Nehmen Sie auch nicht an, dass die ganze Welt die gleichen Zahlen verwendet (d. H. Nicht für Arabisch gilt).

Datums- und Zeitzonen

Daten in Zeiten in Java zu verarbeiten ist zumindest nicht einfach. Wenn Sie nichts anderes als den Gregorianischen Kalender unterstützen möchten, können Sie die integrierten Datums- und Kalenderklassen verwenden. Sie können JSTL fmt: timeZone, fmt: formatDate und fmt: parseDate verwenden, um die Zeitzone korrekt zu setzen, Datum in JSP zu formatieren und zu analysieren.

Ich empfehle dringend, fmt: formatDate wie folgt zu verwenden:

%Vor%

Es ist wichtig, Datum und Uhrzeit in eine gültige (Endbenutzer-) Zeitzone umzuwandeln. Außerdem ist es sehr wichtig, es in ein leicht verständliches Format zu konvertieren - deshalb empfehle ich den Standardformatierungsstil.
Übrigens. Die Zeitzonenerkennung ist nicht einfach, da Webbrowser nicht so nett sind, etwas zu senden. Stattdessen können Sie entweder das bevorzugte Zeitzonenfeld zu den Benutzereinstellungen hinzufügen (falls Sie eines haben) oder den aktuellen Zeitzonen-Offset vom Webbrowser über das clientseitige Skript abrufen (siehe Datenobjektmethoden )

Zahlen und Währungen

Zahlen sowie Währungen sollten in das lokale Format konvertiert werden. Dies geschieht in ähnlicher Weise wie das Formatieren von Daten (das Parsen wird auch ähnlich durchgeführt):

%Vor%

Zusammengesetzte Nachrichten

Sie wurden bereits davor gewarnt, Strings zu verketten. Stattdessen würden Sie wahrscheinlich MessgageFormat verwenden. Ich muss jedoch angeben, dass Sie die Verwendung von zusammengesetzten Nachrichten minimieren sollten. Das liegt nur daran, dass Zielgrammatikregeln ziemlich häufig verschieden sind, so dass Übersetzer nicht nur den Satz neu ordnen müssen (dies würde mit Platzhaltern und MessageFormat.format() gelöst werden), sondern den gesamten Satz auf andere Weise übersetzen ersetzt werden. Lassen Sie mich Ihnen einige Beispiele nennen:

%Vor%

Zeichencodierung

Wenn Sie vorhaben, in Sprachen zu lokalisieren, die die ISO 8859-1-Codepage nicht unterstützen, müssten Sie Unicode unterstützen. Der beste Weg besteht darin, die Seitencodierung auf UTF-8 zu setzen. Ich habe Leute gesehen, die es so gemacht haben:

%Vor%

Ich muss Sie warnen: Das ist nicht genug . Sie brauchen diese Erklärung tatsächlich:

%Vor%

Außerdem müssen Sie die Codierung in der Seitenkopfzeile deklarieren, nur um auf der sicheren Seite zu sein:

%Vor%

Die Liste, die ich Ihnen gegeben habe, ist nicht erschöpfend, aber das ist ein guter Ausgangspunkt. Viel Glück :)

    
Paweł Dyda 23.06.2011, 10:49
quelle
1

Sie können genau dies tun, indem Sie die JSTL-Standard-Tag-Bibliothek mit dem Tag verwenden. Besorgen Sie sich eine Kopie der JSTL-Spezifikation, lesen Sie die i8N-Kapitel, in denen allgemeiner Text, Datum, Uhrzeit und Währung behandelt werden. Sehr übersichtlich geschrieben und zeigt Ihnen, wie Sie alles mit Tags machen können. Sie können auch Dinge wie Locale programmgesteuert festlegen

    
MJB 23.06.2011 02:37
quelle
1

Sie müssen (und sollten nicht) eine separate JSP-Datei pro Gebietsschema haben. Die schwierige Aufgabe besteht darin, die Schlüssel herauszufinden, die nicht i18n-ed sind, und sie in eine Datei pro Gebietsschema zu verschieben, z. B. messages_en.properties, messages_fr.properties und so weiter.

Die Gebietsschemaberechnung kann abhängig von Ihrer Logik an mehreren Stellen erfolgen. Wir unterstützen Benutzer-Locales, die in einer Datenbank gespeichert sind, sowie das Gebietsschema des Browsers. Jede Anfrage, die in Ihre Anwendung kommt, wird eine "Accept-Language" -Kopfzeile haben, die angibt, in welchen Sprachen Ihr Browser konfiguriert wurde, mit Voreinstellungen, d. H. Japanisch zuerst und dann Englisch. Wenn dies der Fall ist, sollte die Anwendung die Datei messages_ja.properties lesen und für Schlüssel, die sich nicht in dieser Datei befinden, auf messages_en.properties zurückgreifen. Dasselbe gilt für Benutzer-Locales, die in der Datenbank gespeichert sind. Bitte beachten Sie, dass der Standard nur darin besteht, die Sprache im Browser zu wechseln und zu erwarten, dass der Inhalt geändert wird. (Anfangs haben wir mit der Speicherung der Ländereinstellung in der Datenbank begonnen und dann verschoben, um Ländereinstellungen aus dem Browser zu unterstützen). Außerdem benötigen Sie einen Standard, da die Übersetzer die Schlüssel und Werte aus dem Englischen (Hauptsprachendatei) nicht in andere Sprachen kopieren können. Daher müssen Sie für Werte, die nicht in anderen Dateien enthalten sind, auf Englisch setzen.

Ich fand mygengo auch sehr nützlich, wenn ich anderen Leuten, die eine bestimmte Sprache kannten, einen Übersetzungsjob gab, und das hat uns viel Zeit gespart.

    
rajasaur 23.06.2011 02:46
quelle

Tags und Links