Java/Velocity, XML/JSON: UTF-8 [UPDATE]

Wer Velocity auf ‘nem Tomcat laufen hat, stolpert vielleicht mal über das Problem, dass das Character Encoding falsch gesetzt ist. Sprich, dass Umlaute falsch gerendert werden.

Nun könnte man vermuten, dass das am String selbst liegt. Tut es nicht: In Java sind Strings UTF-16.

Dann könnte man den Fehler in Velocity suchen. Etwa könnte man die Templates explizit als UTF-8 öffnen:

Das hat bei mir nicht geholfen. Allerdings kann man Velocity das Default-, Input- und Output-Encoding vorgeben:

Das scheint schon mal was zu bewirken. Allerdings wird einem hier auffallen, dass die meisten (wenn nicht alle) Umlaute nicht im Template liegen, sondern dort nur reingeschrieben werden. In unserem Fall wurden zum Beispiel zum Teil Daten eines Webservice, zum Teil aber auch lokal gespeicherte XMLs verwendet. Die XMLs müssen UTF-8-kodiert gespeichert worden sein:

Und sie müssen vor allem auch UTF-8-kodiert gelesen werden:

Update

Kommen die XML-Daten (hier als ZIP) aus der Schnittstelle, müssen sie als UTF-8 in einen String konvertiert werden:

So. Last but not least müssen die Daten, die serverintern jetzt in UTF-8 vorliegen sollten, auch als solches an den Browser ausgegeben werden. Während normalerweise der Writer des Response ausreicht, um den OutputStream dieses Response zu handlen:

, muss man diesen für UTF-8 manchmal mit einem Writer mit explizit gesetztem UTF-8 ersetzen (Danke an Ralf!):

Achtung: Für JSON-Response musste ich dagegen das Encoding des Response selbst setzen:

Vermutlich ist das ein wenig kompliziert gemacht (ich meine, hey, das muss einfacher gehen!), aber so scheint es hier zu funktionieren. HTH

Update

Für Spring gilt es außerdem, dieses Setting zu beachten:

wmode transparent: @-Bug

Der altbekannte Bug, kein @-Zeichen eingeben zu können, wenn der wmode auf transparent steht, sollte in Flash-Player 10.1 behoben sein. Ist er nicht. Zumindest nicht in Chrome. Man nutze diesen Workaround:

Wenn wir auf Windows sind (denn nur hier tritt der Bug auf), erlaube das @-Zeichen nicht als regulären Input. Denn in einigen Browsern tritt der Bug nicht auf, und in diesen Browsern wollen wir keine doppelten @-Zeichen 😉 Außerdem verbieten wir q und Q, denn leider leider kann man auf dem KeyboardEvent kein preventDefault() aufrufen. Wir hätten dann “@q”, bzw “@Q”, statt nur “@”.

Stattdessen prüfen wir jedes eingegebene Zeichen mit dem folgenden Listener auf @/q/Q (KeyCode 81 – unter OS X ist der Code ein anderer). Hier ist zu beachten, dass der Cursor nicht am Ende des Textes stehen muss! Und nicht nur das: Es kann auch Text markiert sein, wenn man das @-Zeichen eingibt. Deshalb die etwas aufwendige Bestimmung des Bereiches, der durch @ ersetzt werden muss. Zum Schluss setzten wir den Cursor hinter das frisch eingegebene Zeichen.

Was mich jetzt noch interessieren würde: In dem Ticket ist die Rede von “ALTGR+2” statt “ALTGR+q”; der Autor des Tickets ist Norweger. Damit wird der obige Code nicht funktionieren, denn KeyCode 81 ist das “q” 🙁 Alternativ habe ich die Prüfung

probiert. Das liefert mir auf OS X das erwünschte Ergebnis (“@”), aber auf Windows ist ALTGR+q das “q” und nicht “@”, ich gehe deshalb davon aus, dass ALTGR+2 die “2” ist 🙁 Gibt es keine international gültige Version, nur mittels KeyboardEvent auf die Eingabe von Sonderzeichen zu prüfen??

(Chemische) Sonderzeichen in XML

Wer Sonderzeichen wie z.B. hochgestellte Ziffern (m3) in XML ablegen möchte, nutzt dieses PDF:

http://crusy.net/files/SonderzeichenXML.pdf

(Quelle: http://www.aumiller.ch/). Wer tiefgestellte Zahlen benötigt, googelt nach “xml special chars Subscript” (ohne Anführungszeichen)… die 2 aus CO2 zum Beispiel lautet ₂

HTH, Lennart