UTF-8 in Java Webapplikationen

Featured

UTF-8 in Java Webapplikationen

UTF-8 in Java Webapplikationen

Dieser Artikel besteht aus zwei Teilen. Der zweite Teil findet sich hier.

Alles bisher veröffentlichten Artikel zur Zeichensatzproblematik finden sich hier: http://www.buildblog.de/tag/zeichensatz/

Die Frage, die hier beantwortet wird umfasst folgendes Problem: Ich möchte eine Java-Webapplikation schreiben, die Internationalisierte Zeichensätze unterstützt. Dazu zählen sowohl die deutschen Umlaute als auch kyrillische oder chinesische Zeichen. Problem: Die Darstellung bestimmter Zeichen im Browser erinnert eher an Bauklötzchen als an irgendwelche bekannten Zeichen.

Das Problem ist vielschichtig denn wir haben hier mit unterschiedlichen Variablen zu Kämpfen:

  • Zeichensatzkodierung des User-Browsers
  • Zeichensatzkodierung des dem Server zugrunde liegenden Betriebssystems
  • Zeichensatzkodierung des Applikation-Servers bzw. Servlet-Containers (ich lege hier Tomcat 5.5 zugrunde, mit Version 6 funktioniert es genau so)
  • Zeichensatzkodierung der Datenbank (ich lege hier MySql zugrunde)
  • Zeichensatzkodierung der Entwicklungsumgebung

Alle diese Variablen unterstützen zwar theoretisch die UTF-8 Kodierung, allerdings bedeutet dies keineswegs, dass diese auch standardmäßig verwendet wird. Und das obwohl UTF-8 seit Jahren als Quasi-Standard im Einsatz ist.

Die Grundlagen

Für die Repräsentation eines jeden Zeichens auf einem Computer wird wird ein bestimmtes Bitmuster verwendet. Die länge des Bitmusters definiert also die Größe eines Zeichens. Im Falle von UTF-8 beträgt der Speicherbedarf pro Zeichen maximal 8Byte. Dafür lassen sich mit dieser Kodierung auch weit über 4Mrd. Zeichen darstellen.

Ich will an dieser Stelle nicht weiter auf die Grundlagen der Zeichensatzkodierung eingehen, des es handelt sich hier um ein Problem mit dem man Bücher füllen könnte. Nur so viel: UTF-8 ist die Lösung jedes bisher aufgetauchten Darstellungs- und Kodierungsproblems.

Die Erforderlichen Schritte

  1. Die Tomcat-Konfiguration anpassen
  2. Einen Charset-Filter bauen oder den eigenen Controller anpassen
  3. Alle dynamischen Seiten (in unserem Falle die JSPs) anpassen
  4. Kodierungsrelevante Meta-Tags setzen
  5. Kritische Request Parameter von GET auf POST umstellen
  6. Sämtliche Datenbankverbindungen anpassen
  7. Die Konfiguration des MySql-Servers ändern
  8. Die Zeichensatzkodierung in den bestehenden Tabellen ändern
  9. Eventuell bestehende StoredProcedures und Functions anpassen
  10. Den Standardzeichensatz bei Start von Tomcat definieren

1. Die Anpassung der Tomcat Konfiguration

Üblicherweise sieht die Einstellung des Standard-HTTP Connectors in Tomcat so oder so Ähnlich aus:

<Connector port=“8080″ maxHttpHeaderSize=“8192″
maxThreads=“150″ minSpareThreads=“25″ maxSpareThreads=“75″
enableLookups=“false” redirectPort=“8443″ acceptCount=“100″
connectionTimeout=“20000″ disableUploadTimeout=“true”
>

Das Problem hierbei betrifft die Kodierung der URI einer Website. Also das, was hinter dem Domainnamen folgt. Dieser Teil wird im Normalfall in einem Latin-1 Derivat kodiert, was etwas ungünstig ist. Wir müssen also dafür sorgen, dass die URI auch den Kodierungsregeln von UTF-8 folgt. Dies geschieht durch Ergänzung des Eintrages um folgende Zeile innerhalb der Definition des Connectors:

URIEncoding=“UTF-8″

2. Erstellung eines Charset-Filters oder Anpassung des bestehenden Controllers

Wollen wir einen eigenen Filter für diesen Zweck erzeugen müssen wir einen Filter anlegen, der innerhalb der Methode doFilter(HttpServletRequest request, HttpServletResponse response) die folgenden sechs Zeilen enthält:

if(request.getCharacterEncoding()==null)
{
request.setCharacterEncoding(encoding);
}

response.setContentType(“text/html; charset=UTF-8″);
response.
setCharacterEncoding(“UTF-8″);

Sollte bereits ein eigener Controller in Form eines Servlets zur Verfügung stehen ergänzen wir die Methode, welche sich um die Auslierung unserer Inhalte kümmert direkt am Anfang der Methode mit den o.g. Zeilen. Gibt der Browser wider erwarten keine Zeichenkodierung für seinen Request vor, wird diese auf UTF-8 gesetzt. Im zweiten Schritt wird dem Browser unserer Nutzer die Kodierung der Antwort mitgeteilt. Für diejenigen, die nicht wissen, wie ein solcher Filter zu realisieren ist:

http://wiki.apache.org/tomcat/Tomcat/UTF-8

3. Anpassung der dynamischen Seiten

Jedes verwendete JSP (auch diejenigen, welche möglicherweise nur per Include eingebettet werden) werden mit folgender Zeile ganz oben im Code ergänzt:

<%@ page pageEncoding=”UTF-8″ contentType=”text/html; charset=UTF-8″%>

4. Setzen Kodierungrelevanter Meta-Tags in statischen Seiten, sowie dynamischen Seiten, die einen HTML-Header beinhalten

Jede Seite die einen HTML-Header, beginnend mit:

<html>

<head>….

enthält, wird mit folgender Zeile innerhalb von <head></head> ergänzt:

<meta http-equiv=’Content-Type’ content=’text/html; charset=UTF-8′ />

5. Kritische Request Parameter von GET auf POST umstellen

Als Kritische Request-Parameter bezeichne ich solche, über die wir nicht die volle Herrschaft haben. Das heißt kritische ist jeder Paramater, den nicht unser eigenes System vorgibt sondern jeder Parameter, den ein Nutzer, z.B. in ein Eingabefeld schreibt. Dazu sollte man kurz auf den Kern dieses Problems eingehen: Die HTTP-Spezifikation sieht eigentlich nur eine Kodierung von GET-Parametern im Latin-1 Standard vor. Dies führt dazu, dass Zeichen die Beispielsweise in ISO-88591 (deutsch) Zeichensatz enthalten sind vom Browser immer mit diesem Kodiert werden, wohingegen Zeichen, die aus diesem Muster fallen (z.B. chinesische) mit der von uns explizit eingestellten Kodierung. Dies bedeutet, dass es für die Webapplikation eigentlich keinerlei Möglichkeit gibt, zweifelsfrei festzustellen, wie die Daten jetzt kodiert sind. Diesem Problem kann auf zwei wegen Begegnen:

  • Entweder man verwendet nur noch Post als Übertragungsmethode, weil die Kodierung der per Post übertragenen Parameter nicht festgeschrieben ist
  • Man verwendet JavaScript zur Kodierung der Parameter

Auf die JavaScript Variante gehe hier ein. Damit also keine unerwarteten Zeichensalat-Effekte auftreten sollte jedes Formular wie folgt aussehen:

<form method=”post” accept-encoding=”UTF-8″>

Weiterlesen…

Diskussion

7 Kommentare zu “UTF-8 in Java Webapplikationen”

  1. Der Post ist nicht schlecht leider funktioniert bei mir nicht!!!
    Die Sonderzeichen (ßüöä) werden unverkennbar (ßüöä) dargestellt.

    Was mache ich falsch?
    Folgende Schritte habe ich gemacht:
    1) Tomcat angepasst
    2) Filter eingebaut
    3) JSP angepasst
    4) Meta-Tags Kodierung gesetzt
    5) form angepasst

    hier ist meine JSP-Seite:

    Charset

    Eingabe:

    Zu Punkt 5:
    ich glaube es soll “accept-charset=”" und nich “accept-encoding=”" heißen.

    Posted by profi.inti | Januar 3, 2009, 00:03
  2. Hier ist der Quell-Code von der JSP-Seite:
    <%–

    Charset

    Eingabe:

    –%>

    Posted by profi.inti | Januar 3, 2009, 00:05
  3. Falls die Sonderzeichenprobleme beim Zugriff auf die Datenbank erscheinen, wird der morgige Post Dein Problem lösen. Falls nicht, hilft es in der Regel beim Parameter Auslesen folgendes zu tun: String sParam = new String(request.getParameter(“param”).getBytes(“UTF-8″));

    Falls es sich um ein Problem im Zusammenhang mit Ajax handelt: Alle Parameter müssen separat mit der Methode escape() kodiert werden.

    Posted by Hathead | Januar 3, 2009, 02:53
  4. [...] Artikel ist die Fortsetzung meines ersten Beitrags UTF-8 in Java Webapplikationen. Um nochmal kurz zusammen zu fassen. Zur ordnungsgemäßen verwendung von UTF-8 im Zusammenhang mit [...]

    Posted by buildblog | UTF-8 in Java Webapplikationen Teil 2 | Januar 3, 2009, 20:55
  5. Ist ja toll, dass eines meiner letzten Programmierprobleme gleich in 2 Artikeln behandelt wird.

    Auch wenn ich mein Problem anders lösen musste als mittels Internationalisierung…

    Allerdings ist dies wohl der deutlich bessere Weg…

    Posted by abs | Januar 7, 2009, 12:12
  6. [...] in Java Webapplikationen Teil 1 und Teil [...]

    Posted by buildblog | Buildblog im Januar | Februar 7, 2009, 19:40
  7. [...] Wie gesagt. Ich schreibe mal was ausführliches dazu. . . . 7.) Wie steht es denn um deine unique visits/Seitenaufrufe pro Tag und wie steht es um deinen Traffic? Das wird Dich jetzt vermutlich erstaunen. Es ist sind nur zwischen 150 und 500 visits am Tag. Letzeres ist eher selten. Derzeit scheint sich das ganze bei 200 am Tag einzupendeln. Der Durchschnittsuser bleibt 2:14 auf der Seite und macht 1,9 Klicks. . . . 8.) Nenne mir doch bitte 3 deiner Artikel, welche am meisten gelesen oder kommentiert wurde und füge bitte hinzu, wieso dies wohl so ist. Meist gelesen: http://www.buildblog.de/2009/10/11/usenext-erwagt-rechtliche-schritte-gegen-buildblog-verantwortliche/ http://www.buildblog.de/2009/05/01/ajax-und-umlaute-das-ewig-wahrende-utf-8-problem-und-seine-losung/ http://www.buildblog.de/2009/01/02/utf-8-in-java-webapplikationen/ [...]

    Posted by Interview mit Buildblog | Antworten für Blogger | April 5, 2010, 13:20

Post a comment

XING