Wie funktioniert UTF-8 in Java-Webapps?

Ich muss UTF-8 in meiner Java-Webapp (Servlets + JSP, kein Framework verwendet) verwenden, um äöå usw. für normale finnische Texte und kyrillische Alphabete wie ЦжФ für Sonderfälle zu unterstützen.

Mein Setup ist folgendes:

  • Entwicklungsumgebung: Windows XP
  • Produktionsumgebung: Debian

Verwendete database: MySQL 5.x

Die Benutzer verwenden hauptsächlich Firefox2, aber auch Opera 9.x, FF3, IE7 und Google Chrome werden verwendet, um auf die Seite zuzugreifen.

Wie erreiche ich das?

Solutions Collecting From Web of "Wie funktioniert UTF-8 in Java-Webapps?"

Beantworten Sie mich als FAQ dieser Seite ermutigt es. Das funktioniert für mich:

Meistens sind Zeichen äåö kein Problem, da der Standardzeichensatz, der von Browsern verwendet wird, und tomcat / java für Webapps latin1 ist, dh. ISO-8859-1, die diese Zeichen “versteht”.

Um UTF-8 unter Java + Tomcat + Linux / Windows + MySQL zu verwenden, ist Folgendes erforderlich:

Konfigurieren von Tomcat’s server.xml

Es muss konfiguriert werden, dass der Connector UTF-8 zum Codieren von URL-Parametern (GET-Anforderung) verwendet:

  

Der Schlüssel ist URIEncoding = “UTF-8” im obigen Beispiel. Dies garantiert, dass Tomcat alle eingehenden GET-Parameter als UTF-8-codiert behandelt. Wenn der Benutzer Folgendes in die Adressleiste des Browsers schreibt:

  https://localhost:8443/ID/Users?action=search&name=*ж* 

das Zeichen Ö wird als UTF-8 behandelt und wird (normalerweise vom Browser, bevor es überhaupt zum Server gelangt ) als % D0% B6 codiert.

POST-Anfragen sind davon nicht betroffen.

CharsetFilter

Dann ist es an der Zeit, die Java Webapp zu zwingen, alle Anfragen und Antworten als UTF-8 verschlüsselt zu behandeln. Dazu müssen wir einen Zeichensatzfilter wie den folgenden definieren:

 package fi.foo.filters; import javax.servlet.*; import java.io.IOException; public class CharsetFilter implements Filter { private String encoding; public void init(FilterConfig config) throws ServletException { encoding = config.getInitParameter("requestEncoding"); if (encoding == null) encoding = "UTF-8"; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain next) throws IOException, ServletException { // Respect the client-specified character encoding // (see HTTP specification section 3.4.1) if (null == request.getCharacterEncoding()) { request.setCharacterEncoding(encoding); } // Set the default response content type and encoding response.setContentType("text/html; charset=UTF-8"); response.setCharacterEncoding("UTF-8"); next.doFilter(request, response); } public void destroy() { } } 

Dieser Filter stellt sicher, dass, wenn der Browser die in der Anfrage verwendete Codierung nicht eingestellt hat, diese auf UTF-8 eingestellt ist.

Die andere Sache, die von diesem Filter gemacht wird, ist das Setzen der Standard-Antwort-Codierung, dh. die Codierung, in der der zurückgegebene html / was auch immer ist. Die Alternative besteht darin, die Antwortcodierung usw. in jedem Controller der Anwendung einzustellen.

Dieser Filter muss der web.xml oder dem Deployment Deskriptor der Webapp hinzugefügt werden:

    CharsetFilter fi.foo.filters.CharsetFilter  requestEncoding UTF-8    CharsetFilter /*  

Die Anleitung zum Erstellen dieses Filters finden Sie im Tomcat Wiki ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )

JSP-Seitencodierung

Fügen Sie in Ihrer web.xml Folgendes hinzu:

   *.jsp UTF-8   

Alternativ müßten alle JSP-Seiten der Webapp an deren Spitze stehen:

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

Wenn irgendeine Art von Layout mit unterschiedlichen JSP-Fragmenten verwendet wird, wird dies in allen von ihnen benötigt.

HTML-Metatags

Die JSP-Seitencodierung weist die JVM an, die Zeichen auf der JSP-Seite in der richtigen Codierung zu verarbeiten. Dann ist es Zeit, dem Browser mitzuteilen, in welcher Kodierung die HTML-Seite ist:

Dies geschieht am oberen Rand jeder xhtml-Seite, die von der Webapp erzeugt wird:

  < ?xml version="1.0" encoding="UTF-8"?> < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">    ... 

JDBC-Verbindung

Wenn eine db verwendet wird, muss definiert werden, dass die Verbindung die UTF-8-Codierung verwendet. Dies geschieht in context.xml oder überall dort, wo die JDBC-Verbindung wie folgt definiert ist:

   

MySQL database und Tabellen

Die verwendete database muss UTF-8-Codierung verwenden. Dies wird erreicht, indem die database mit folgendem erstellt wird:

  CREATE DATABASE `ID_development` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */; 

Dann müssen alle Tabellen auch in UTF-8 sein:

  CREATE TABLE `Users` ( `id` int(10) unsigned NOT NULL auto_increment, `name` varchar(30) collate utf8_swedish_ci default NULL PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci ROW_FORMAT=DYNAMIC; 

Der Schlüsselteil ist CHARSET = utf8 .

MySQL-Serverkonfiguration

MySQL Serveri muss auch konfiguriert werden. In der Regel erfolgt dies in Windows durch Änderung der Datei my.ini und in Linux durch Konfiguration der Datei my.cnf. In diesen Dateien sollte definiert werden, dass alle Clients, die mit dem Server verbunden sind, utf8 als Standardzeichensatz verwenden und dass der Standardzeichensatz, der vom Server verwendet wird, ebenfalls utf8 ist.

  [client] port=3306 default-character-set=utf8 [mysql] default-character-set=utf8 

Mysql Verfahren und functionen

Diese müssen auch den definierten Zeichensatz haben. Beispielsweise:

  DELIMITER $$ DROP FUNCTION IF EXISTS `pathToNode` $$ CREATE FUNCTION `pathToNode` (ryhma_id INT) RETURNS TEXT CHARACTER SET utf8 READS SQL DATA BEGIN DECLARE path VARCHAR(255) CHARACTER SET utf8; SET path = NULL; ... RETURN path; END $$ DELIMITER ; 

GET-Anfragen: latin1 und UTF-8

Wenn und wenn in der server.xml von tomcat definiert ist, dass GET-Anforderungsparameter in UTF-8 codiert sind, werden die folgenden GET-Anforderungen richtig gehandhabt:

  https://localhost:8443/ID/Users?action=search&name=Petteri https://localhost:8443/ID/Users?action=search&name=ж 

Da ASCII-Zeichen sowohl bei latin1 als auch bei UTF-8 gleich codiert sind, wird die Zeichenfolge “Petteri” korrekt behandelt.

Das kyrillische Zeichen Ö wird in latin1 überhaupt nicht verstanden. Da Tomcat angewiesen wird, Anforderungsparameter als UTF-8 zu behandeln, codiert es dieses Zeichen korrekt als % D0% B6 .

Wenn und wenn Browser angewiesen werden, die Seiten in UTF-8-Codierung (mit Anforderungsheadern und HTML-Meta-Tag) zu lesen, codieren zumindest Firefox 2/3 und andere Browser aus dieser Periode das Zeichen selbst als % D0% B6 .

Das Endergebnis ist, dass alle Benutzer mit dem Namen “Petteri” gefunden werden und auch alle Benutzer mit dem Namen “Ö” gefunden werden.

Aber was ist mit äåö?

Die HTTP-Spezifikation definiert, dass URLs standardmäßig als latin1 codiert werden. Dies führt dazu, dass firefox2, firefox3 usw. das Folgende codieren

  https://localhost:8443/ID/Users?action=search&name=*Päivi* 

in die verschlüsselte Version

  https://localhost:8443/ID/Users?action=search&name=*P%E4ivi* 

In latin1 ist das Zeichen ä als % E4 codiert. Obwohl die Seite / request / everything für die Verwendung von UTF-8 definiert wurde . Die UTF-8-codierte Version von ä ist % C3% A4

Dies führt dazu, dass es für die Webanwendung ziemlich unmöglich ist, die Anforderungsparameter von GET-Anforderungen korrekt zu handhaben, da einige Zeichen in latin1 und andere in UTF-8 codiert sind. Hinweis: POST-Anfragen funktionieren, da Browser alle Anforderungsparameter aus Formularen vollständig in UTF-8 codieren, wenn die Seite als UTF-8 definiert ist

Sachen zum lesen

Ein sehr großes Dankeschön für die Autoren der folgenden, die Antworten auf mein Problem gegeben haben:

Wichtige Notiz

mysql unterstützt die Basic Multilingual Plane mit 3-Byte-UTF-8-Zeichen. Wenn Sie darüber VARBINARY müssen (bestimmte Alphabete benötigen mehr als 3 Byte UTF-8), müssen Sie entweder den Flavour-Typ VARBINARY verwenden oder den Zeichensatz utf8mb4 verwenden (für den MySQL 5.5.3 oder höher erforderlich ist) ). Beachten Sie jedoch, dass die Verwendung des utf8 Zeichensatzes in MySQL nicht zu 100% funktioniert.

Tomcat mit Apache

Eine weitere Sache Wenn Sie Apache + Tomcat + mod_JK Connector verwenden, müssen Sie auch folgende Änderungen vornehmen:

  1. Fügen Sie URIEncoding = “UTF-8” in tomcat server.xml-Datei für 8009-Connector hinzu, es wird vom mod_JK-Connector verwendet.
  2. Gehe zu deinem Apache-Ordner dh /etc/httpd/conf und füge AddDefaultCharset utf-8 in der httpd.conf file . Hinweis: Überprüfen Sie zuerst, ob es existiert oder nicht. Falls vorhanden, können Sie es mit dieser Zeile aktualisieren. Sie können diese Zeile auch unten hinzufügen.

Ich denke, du hast es in deiner eigenen Antwort sehr gut zusammengefasst.

Im Verlauf von UTF-8-ing (?) Von Ende zu Ende möchten Sie vielleicht auch sicherstellen, dass Java selbst UTF-8 verwendet. Verwenden Sie -Dfile.encoding = utf-8 als Parameter für die JVM (kann in catalina.bat konfiguriert werden).

Um die Antwort von kosoant hinzuzufügen, wenn Sie Spring verwenden, anstatt Ihren eigenen Servlet-Filter zu schreiben, können Sie die von Ihnen angebotene class org.springframework.web.filter.CharacterEncodingFilter verwenden, org.springframework.web.filter.CharacterEncodingFilter Sie sie wie folgt in Ihrer web.xml konfigurieren:

   encoding-filter org.springframework.web.filter.CharacterEncodingFilter  encoding UTF-8   forceEncoding FALSE    encoding-filter /*  

Dies ist für die griechische Codierung in MySql-Tabellen, wenn wir mit Java darauf zugreifen wollen:

Verwenden Sie das folgende Verbindungs-Setup in Ihrem JBoss-Verbindungspool (mysql-ds.xml)

 jdbc:mysql://192.168.10.123:3308/mydatabase com.mysql.jdbc.Driver nts xaxaxa! true greek 

Wenn Sie dies nicht in einen JNDI-Verbindungspool einfügen möchten, können Sie es wie in der folgenden Zeile als JDBC-URL konfigurieren:

 jdbc:mysql://192.168.10.123:3308/mydatabase?characterEncoding=greek 

Für mich und Nick, damit wir es nie vergessen und Zeit verschwenden …..

Schöne detaillierte Antwort. Ich wollte nur noch eine Sache hinzufügen, die anderen auf jeden Fall helfen wird, die UTF-8-Codierung für URLs in Aktion zu sehen.

Führen Sie die folgenden Schritte aus, um die UTF-8-Codierung für URLs in Firefox zu aktivieren.

  1. Geben Sie in der Adressleiste “about: config” ein.

  2. Verwenden Sie den Filtereingabetyp, um nach der Eigenschaft “network.standard-url.encode-query-utf8” zu suchen.

  3. Die obige Eigenschaft wird standardmäßig falsch sein, drehen Sie das auf TRUE.
  4. starte den Browser neu.

UTF-8-Codierung für URLs funktioniert standardmäßig in IE6 / 7/8 und Chrome.

Ich möchte auch hinzufügen , dass dieser Teil mein utf-Problem getriggers hat:

 runtime.encoding= 

Ich bin mit einem ähnlichen Problem, aber in Dateinamen einer Datei komprimiere ich mit Apache Commons. Also, ich habe es mit diesem Befehl getriggers:

 convmv --notest -f cp1252 -t utf8 * -r 

es funktioniert sehr gut für mich. Hoffe es hilft jedem;)

Für meinen Fall, Unicode-Zeichen aus Nachrichtenbündeln anzuzeigen, muss ich den Abschnitt “JSP-Seitencodierung” nicht anwenden, um Unicode auf meiner JSP-Seite anzuzeigen. Alles, was ich brauche, ist der Abschnitt “CharsetFilter”.

Ein weiterer Punkt, der nicht erwähnt wurde, bezieht sich auf Java-Servlets, die mit Ajax arbeiten. Ich habe Situationen, in denen eine Webseite utf-8-Text vom Benutzer abruft, der dieses an eine JavaScript-Datei sendet, die es in einem URI enthält, der an das Servlet gesendet wird. Das Servlet fragt eine database ab, erfasst das Ergebnis und gibt es als XML an die JavaScript-Datei zurück, die es formatiert und die formatierte Antwort in die ursprüngliche Webseite einfügt.

In einer Web-App folgte ich den statementen eines frühen Ajax-Buches, wie man JavaScript beim Erstellen des URI einpackt. Das Beispiel im Buch verwendet die Methode escape (), die ich entdeckt habe (auf die harte Tour) ist falsch. Für utf-8 müssen Sie encodeURIComponent () verwenden.

Nur wenige Leute scheinen heutzutage ihre eigenen Ajax zu rollen, aber ich dachte, ich könnte das genauso gut hinzufügen.

Über CharsetFilter in @kosoant Antwort erwähnt ….

In conf/web.xml web.xml (unter conf/web.xml ) ist ein Filter conf/web.xml . Der Filter heißt setCharacterEncodingFilter und ist standardmäßig kommentiert. Sie können das Kommentarzeichen entfernen (Bitte beachten Sie, dass Sie das filter-mapping auskommentieren)

Es ist auch nicht notwendig, jsp-config in der web.xml (ich habe es für Tomcat 7+ getestet)

Irgendwann können Sie das Problem mit dem MySQL Administrator Assistenten lösen. Im

Startup-Variablen> Erweitert>

und Def. einstellen Zeichensatz: utf8

Vielleicht muss diese Konfiguration MySQL neu starten.

Vorherige Antworten funktionierten nicht mit meinem Problem. Es war nur in der Produktion, mit Tomcat und Apache mod_proxy_ajp. Post Körper verlor nicht ascii Zeichen durch? Das Problem war schließlich mit JVM defaultCharset (US-ASCII in einer Standardinstallation: Charset dfset = Charset.defaultCharset ();), so dass die Lösung Tomcat-Server mit einem Modifizierer ausgeführt wurde, um die JVM mit UTF-8 als Standard-Zeichensatz auszuführen:

 JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8" 

(Fügen Sie diese Zeile zu catalina.sh und service tomcat restart hinzu)

Vielleicht müssen Sie auch die Linux-Systemvariable ändern (bearbeiten Sie ~ / .bashrc und ~ / .profile für permanente Änderungen, siehe https://perlgeek.de/de/article/set-up-a-clean-utf8-environment )

export LC_ALL = en_US.UTF-8
Export LANG = de_DE.UTF-8

Export LANGUAGE = de_DE.UTF-8

Falls Sie im Verbindungspool (mysql-ds.xml) angegeben haben, können Sie die Verbindung in Ihrem Java-Code wie folgt öffnen:

 DriverManager.registerDriver(new com.mysql.jdbc.Driver()); Connection conn = DriverManager.getConnection( "jdbc:mysql://192.168.1.12:3308/mydb?characterEncoding=greek", "Myuser", "mypass");