Wenn ich als FAQ dieser Website antworte, wird dies gefördert. Das funktioniert bei mir:
Meistens sind Zeichen äåö kein Problem, da der von Browsern und Tomcat / Java für Webapps verwendete Standardzeichensatz latin1 ist, d. H. ISO-8859-1, die diese Zeichen "versteht".
Damit UTF-8 unter Java + Tomcat + Linux / Windows + MySQL funktioniert, ist Folgendes erforderlich:
Konfigurieren der server.xml von Tomcat
Es muss konfiguriert werden, dass der Connector UTF-8 verwendet, um URL-Parameter (GET-Anforderung) zu codieren:
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"
compression="on"
compressionMinSize="128"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/ javascript,application/x-javascript,application/javascript"
URIEncoding="UTF-8"
/>
Der Schlüsselteil 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 als % D0% B6 (normalerweise vom Browser, bevor es überhaupt zum Server gelangt ) codiert .
POST-Anfragen sind davon nicht betroffen.
Zeichensatzfilter
Dann ist es Zeit, die Java-Webanwendung zu zwingen, alle Anforderungen und Antworten als UTF-8-codiert zu verarbeiten. Dies erfordert, dass wir einen Zeichensatzfilter wie folgt 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 UTF-8 festgelegt ist, wenn der Browser die in der Anforderung verwendete Codierung nicht festgelegt hat.
Die andere Aufgabe dieses Filters besteht darin, die Standardantwortcodierung festzulegen, d. H. die Kodierung, in der das zurückgegebene HTML / was auch immer ist. Die Alternative besteht darin, die Antwortcodierung usw. in jedem Controller der Anwendung festzulegen.
Dieser Filter muss der Datei web.xml oder dem Bereitstellungsdeskriptor der Webanwendung hinzugefügt werden:
<!--CharsetFilter start-->
<filter>
<filter-name>CharsetFilter</filter-name>
<filter-class>fi.foo.filters.CharsetFilter</filter-class>
<init-param>
<param-name>requestEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharsetFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Die Anweisungen 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-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Alternativ müssten auf allen JSP-Seiten der Webanwendung Folgendes angezeigt werden:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Wenn eine Art Layout mit verschiedenen JSP-Fragmenten verwendet wird, ist dies in allen erforderlich .
HTML-Meta-Tags
Die JSP-Seitencodierung weist die JVM an, die Zeichen auf der JSP-Seite in der richtigen Codierung zu behandeln. Dann ist es Zeit, dem Browser mitzuteilen, in welcher Codierung die HTML-Seite ist:
Dies geschieht oben auf jeder von der Webanwendung erstellten xhtml-Seite wie folgt:
<?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">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi">
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
...
JDBC-Verbindung
Bei Verwendung einer Datenbank muss definiert werden, dass die Verbindung eine UTF-8-Codierung verwendet. Dies erfolgt in context.xml oder überall dort, wo die JDBC-Verbindung fehlerhaft ist, wie folgt:
<Resource name="jdbc/AppDB"
auth="Container"
type="javax.sql.DataSource"
maxActive="20" maxIdle="10" maxWait="10000"
username="foo"
password="bar"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/ ID_development?useEncoding=true&characterEncoding=UTF-8"
/>
MySQL-Datenbank und -Tabellen
Die verwendete Datenbank muss UTF-8-Codierung verwenden. Dies wird erreicht, indem die Datenbank wie folgt 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 Server Konfiguration
MySQL Serveri muss ebenfalls konfiguriert werden. In der Regel erfolgt dies unter Windows durch Ändern der Datei my.ini und unter Linux durch Konfigurieren der Datei my.cnf. In diesen Dateien sollte definiert werden, dass alle mit dem Server verbundenen Clients utf8 als Standardzeichensatz verwenden und dass der vom Server verwendete Standardzeichensatz auch utf8 ist.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
MySQL-Prozeduren und -Funktionen
Für diese muss auch der Zeichensatz definiert sein. Zum Beispiel:
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 in tomcats server.xml definiert ist, dass GET-Anforderungsparameter in UTF-8 codiert sind, werden die folgenden GET-Anforderungen ordnungsgemäß behandelt:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Da ASCII-Zeichen sowohl mit latin1 als auch mit UTF-8 auf die gleiche Weise codiert werden, wird die Zeichenfolge "Petteri" korrekt behandelt.
Das kyrillische Zeichen ж wird im Lateinischen1 überhaupt nicht verstanden. Da Tomcat angewiesen wird, Anforderungsparameter als UTF-8 zu behandeln, wird dieses Zeichen korrekt als % D0% B6 codiert .
Wenn Browser angewiesen werden, die Seiten in UTF-8-Codierung (mit Anforderungsheadern und HTML-Meta-Tag) zu lesen, codieren mindestens Firefox 2/3 und andere Browser aus dieser Zeit das Zeichen selbst als % D0% B6 .
Das Endergebnis ist, dass alle Benutzer mit dem Namen "Petteri" und auch alle Benutzer mit dem Namen "ж" gefunden werden.
Aber was ist mit äåö?
Die HTTP-Spezifikation definiert, dass URLs standardmäßig als latin1 codiert sind. Dies führt dazu, dass Firefox2, Firefox3 usw. Folgendes codiert
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 wird das Zeichen ä als % E4 codiert . Obwohl die Seite / Anfrage / alles für die Verwendung von UTF-8 definiert ist . Die UTF-8-codierte Version von ä ist % C3% A4
Dies hat zur Folge, dass die Webanwendung die Anforderungsparameter von GET-Anforderungen nicht richtig verarbeiten kann, da einige Zeichen in latin1 und andere in UTF-8 codiert sind.
Hinweis: POST-Anforderungen funktionieren, wenn Browser alle Anforderungsparameter aus Formularen vollständig in UTF-8 codieren, wenn die Seite als UTF-8 definiert ist
Sachen zum Lesen
Ein großes Dankeschön an die folgenden Autoren für die Antworten auf mein Problem:
- http://tagunov.tripod.com/i18n/i18n.html
- http://wiki.apache.org/tomcat/Tomcat/UTF-8
- http://java.sun.com/developer/technicalArticles/Intl/HTTPCharset/
- http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html
- http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-tomcat-jsp-etc.html
- http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-for-mysql-tomcat.html
- http://jeppesn.dk/utf-8.html
- http://www.nabble.com/request-parameters-mishandle-utf-8-encoding-td18720039.html
- http://www.utoronto.ca/webdocs/HTMLdocs/NewHTML/iso_table.html
- http://www.utf8-chartable.de/
Wichtige Notiz
MySQLunterstützt die grundlegende mehrsprachige Ebene mit 3-Byte-UTF-8-Zeichen. Wenn Sie darüber hinausgehen müssen (bestimmte Alphabete erfordern mehr als 3 Byte UTF-8), müssen Sie entweder eine VARBINARY
Spalte vom Spaltentyp verwenden oder den utf8mb4
Zeichensatz 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 100% der Zeit funktioniert.
Kater mit Apache
Eine weitere Sache Wenn Sie den Apache + Tomcat + mod_JK-Connector verwenden, müssen Sie auch folgende Änderungen vornehmen:
- Fügen Sie URIEncoding = "UTF-8" in die Datei tomcat server.xml für den 8009-Connector ein. Dieser wird vom mod_JK-Connector verwendet.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- Goto Ihren Apache Ordner dh ,
/etc/httpd/conf
und fügen Sie AddDefaultCharset utf-8
in httpd.conf file
. Hinweis: Überprüfen Sie zunächst, ob es vorhanden ist oder nicht. Falls vorhanden, können Sie es mit dieser Zeile aktualisieren. Sie können diese Zeile auch unten hinzufügen.