EsPresto.org

Dienstag, 24. Februar 2009

Encoding: UTF-8 für HttpClient und POST requests

Eigentlich ist ja eines der angenehmen Features von Java, dass Strings immer Unicode sind, und man keine Encoding-probleme hat ... jedenfalls so lange nicht, bis man mit der Aussenwelt in Kontakt tritt.
Dann aber gab es immer die Frage, welche der 8bit Stringdarstellungen denn nun "die Richtige" ist, oder auch erstmal, wo bitte die vielen "?" im Text herkommen. Seit sich UTF-8 praktisch durchgesetzt hat, stellt sich diese Frage anders: "Wo ist bei der Schnittstelle die Konfigurationsoption, in der ich 'UTF-8' eintragen muss?"

Im Kontext von Web-servern und -applicationen gibt es da schon genügend Beispiele, wo überall konfiguriert werden muss, damit sowohl Request als auch Response in UTF-8 über die Leitung gehen.

Neulich ist mir das Problem bei einen anderen Kandiaten über den Weg gelaufen, wo ich die Konfiguration noch nicht kannte.

Der Kandidat ist der apache-commons HttpClient (genauer gesagt die org.apache.commons.httpclient.methods.PostMethod klasse in der Library).
Mit HttpClient lassen sich bekanntlich eben mal schnell Verbindungen zu anderen Webservern aufbauen und Inhalte abholen - das Java-Äquivalent zu wget und/oder curl in Shell scripten.

Muss man die Daten via POST verschicken, sieht das in etwa so aus:


 HttpClient client = new HttpClient();
 PostMethod postMethod = new PostMethod( someUrl );
 postMethod.getParams().setContentCharset("utf-8"); // (!) hier wird das encoding gesetzt
 postMethod.addParameter("data", someNonAsciiData );

 int billingReturnCode = billingClient.executeMethod( billingMethod );
 String responseStr
   = request.getResponseBodyAsString(); // wenn man sicher ist, text zurueckzubekommen

Damit die Daten korrekt UTF-8 codiert (bzw in die entsprechenden URL-encodierte Form gebracht wird), muss dabei in der "params" Property der contentCharset korrekt gesetzt werden - sonst nimmt HttpClient den "historischen" Default-wert "ISO-8859-1", und nicht UTF-8.

Bei GET-Requests besteht das Problem nicht - da hält sich HttpClient an die Empfehlung der RFC 3986, UTF-8 zu benutzen, solange nichts anderes angegeben ist. (Wer hier unbedingt etwas anderes haben will, weil zum Beispiel mit einem altersstarrsinnigen Server kommuniziert werden soll, kann das URL Encoding ändern, z.B. mit method.getParams().setUriCharset("iso-8859-1") ).

Getestet mit der (alten) commns-httpclient-3.1.jar ... mit Version 4.0, die gerade in beta-stadium ist, ist es wohl wieder anders geworden. Das probiere ich aber ein anderes mal aus, wenn das entweder stabil ist, oder ich Zeit für Experimente habe ...

Nachtrag: Wer aus irgendwelchen Gründen mit httpclient-2.x arbeitet (zum Beispiel, weil maven einem diese Version über irgendwelchen Abhängigkeiten unterjubelt), muss dem HttpClient das Encoding statt dessen über folgenden VooDoo Tanz unterjubeln:


 postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")

Da ist in etwa äquivalent zu Servlets, bei denen das Encoding in der Reponse auch über den Content-Type gesetzt wird, z.b. durch den Aufruf: response.setContentType("text/html; charset=UTF-8"); ... nur das beim HttpClient der Teil vor dem charset etwas länger ist. Der "charset=utf-8" wird das vom Request aus dem "Content-Type" Header manuell herausgeparsed.

Kommentare:

Encoding und Zeitzonen sind die beiden großen unlösbaren Probleme der Welt.. viele Grüße an euch alle! konrad

Gesendet von konz am Februar 24, 2009 at 05:51 PM CET #

Hi Konrad ... encoding wäre ja kein Problem, wenn sich mal alle auf UTF-8 geeinigt hätten. Das passiert aber wohl nicht mehr in diesem Jahrhundert. Oh, und ich sehe gerade, dass die Benachrichtigungsmail für Kommentare das "ü" in der Betreffzeile falsch kodiert hat :) ... jaja, JavaMail muss auch immer erst nach UTF-8 gebeten werden, da kann ich gleich mal einen bugreport an jroller schreiben ... Schöne Grüsse, Clemens

Gesendet von Clemens Robbenhaar am Februar 25, 2009 at 09:42 AM CET #

Bestimmt gibt's irgendwo in einer bereits ungesichteten Property-Datei eine Einstellung fuer das korrekte Encoding.... Schau ich mir die Tage in einer freien Minute mal an. BTW: Hallo Konrad :))

Gesendet von Tobi am Februar 25, 2009 at 10:55 AM CET #

Jaja, das Encoding. Viele Gr??e auch von mir!

Gesendet von Björn am Februar 28, 2009 at 09:43 AM CET #

Senden Sie einen Kommentar:
  • HTML Syntax: Ausgeschaltet