Ich antworte mir selbst, da die FAQ dieser Website dazu anregen. Das funktioniert für mich:
Die meisten Zeichen äåö sind unproblematisch, da der von Browsern und Tomcat/Java für Webanwendungen verwendete Standardzeichensatz latin1, d. h. ISO-8859-1 ist, der diese Zeichen "versteht".
Um UTF-8 unter Java+Tomcat+Linux/Windows+Mysql zum Laufen zu bringen, ist Folgendes erforderlich:
Die server.xml von Tomcat konfigurieren
Es muss konfiguriert werden, dass der Konnektor UTF-8 zur Kodierung von url-Parametern (GET-Anfrage) verwendet:
<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 wichtigste Teil ist URIEncoding="UTF-8" im obigen Beispiel. Damit wird sichergestellt, dass Tomcat alle eingehenden GET-Parameter als UTF-8 kodiert behandelt. Wenn der Benutzer das Folgende in die Adressleiste des Browsers schreibt, hat dies zur Folge, dass
https://localhost:8443/ID/Users?action=search&name=**
wird das Zeichen als UTF-8 behandelt und (in der Regel vom Browser, noch bevor es den Server erreicht) als %D0%B6 .
POST-Anfragen sind hiervon nicht betroffen.
CharsetFilter
Dann ist es an der Zeit, die Java-Webapp zu zwingen, alle Anfragen und Antworten als UTF-8 kodiert 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 Kodierung nicht festgelegt hat, diese auf UTF-8 gesetzt wird.
Außerdem legt dieser Filter die Standardkodierung der Antwort fest, d. h. die Kodierung, in der die zurückgegebene HTML-Datei bzw. das zurückgegebene Dokument vorliegt. Die Alternative ist, die Antwortkodierung usw. in jedem Controller der Anwendung festzulegen.
Dieser Filter muss in der web.xml oder der Bereitstellungsdeskriptor der Webapp:
<!--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 Anleitung zur Herstellung dieses Filters finden Sie auf der Website tomcat wiki ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
JSP-Seitenkodierung
In Ihrem web.xml fügen Sie Folgendes hinzu:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Alternativ dazu müssten alle JSP-Seiten der Webapplikation am Anfang Folgendes enthalten
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Wenn eine Art von Layout mit verschiedenen JSP-Fragmenten verwendet wird, dann wird dies in alle von ihnen.
HTML-Meta-Tags
Die JSP-Seitenkodierung weist die JVM an, die Zeichen in der JSP-Seite in der richtigen Kodierung zu behandeln. Dann ist es an der Zeit, dem Browser mitzuteilen, in welcher Kodierung die HTML-Seite vorliegt:
Dies geschieht mit dem folgenden Text am Anfang jeder von der Webapp erstellten xhtml-Seite:
<?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 der Verwendung einer Datenbank muss festgelegt werden, dass die Verbindung die Kodierung UTF-8 verwendet. Dies geschieht in kontext.xml oder wo immer die JDBC-Verbindung wie folgt definiert ist:
<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 die Kodierung UTF-8 verwenden. Dies wird durch die Erstellung der Datenbank mit dem folgenden erreicht:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Dann müssen alle Tabellen auch in UTF-8 vorliegen:
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 wichtigste Teil ist CHARSET=utf8 .
Konfiguration des MySQL-Servers
Der MySQL-Serveri muss ebenfalls konfiguriert werden. Normalerweise geschieht dies unter Windows durch Ändern von meine.ini -Datei und unter Linux durch Konfiguration von meine.cnf -Datei. In diesen Dateien sollte festgelegt werden, dass alle mit dem Server verbundenen Clients utf8 als Standardzeichensatz verwenden und dass der vom Server verwendete Standardzeichensatz ebenfalls utf8 ist.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Mysql-Prozeduren und -Funktionen
Auch für diese muss 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 der server.xml von Tomcat definiert ist, dass GET-Anforderungsparameter in UTF-8 kodiert sind, werden die folgenden GET-Anforderungen ordnungsgemäß verarbeitet:
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 kodiert werden, wird die Zeichenfolge "Petteri" korrekt behandelt.
Das kyrillische Zeichen wird im Lateinischen1 überhaupt nicht verstanden. Da Tomcat angewiesen ist, Anfrageparameter als UTF-8 zu behandeln, kodiert er dieses Zeichen korrekt als %D0%B6 .****
Wenn die Browser angewiesen werden, die Seiten in UTF-8-Kodierung zu lesen (mit Anfragekopfzeilen und html-Meta-Tag), kodieren zumindest 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" gefunden werden und auch alle Benutzer mit dem Namen "" gefunden werden.
Aber was ist mit äåö?
Die HTTP-Spezifikation legt fest, dass URLs standardmäßig als latin1 kodiert werden. Dies führt dazu, dass firefox2, firefox3 usw. folgendes kodieren
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*
Im lateinischen1 wird das Zeichen ä wird kodiert als %E4 . Obwohl page/request/everything für die Verwendung von UTF-8 definiert ist . Die UTF-8 kodierte Version von ä ist %C3%A4
Dies hat zur Folge, dass es für die Webanwendung unmöglich ist, die Anfrageparameter von GET-Anfragen korrekt zu verarbeiten, da einige Zeichen in latin1 und andere in UTF-8 kodiert sind. Hinweis: POST-Anfragen funktionieren, da die Browser alle Anfrageparameter von Formularen vollständig in UTF-8 kodieren, wenn die Seite als UTF-8 definiert ist.
Lesenswertes
Ein herzliches Dankeschön an die Verfasser der folgenden Beiträge für die Antworten auf mein Problem:
Wichtiger Hinweis
mysql Basic Multilingual Plane unter Verwendung von 3-Byte-UTF-8-Zeichen. Wenn Sie darüber hinausgehen müssen (bestimmte Alphabete erfordern mehr als 3 Byte UTF-8), dann müssen Sie entweder eine Variante von VARBINARY
Spaltentyp oder verwenden Sie die utf8mb4
Zeichensatz (hierfür ist MySQL 5.5.3 oder höher erforderlich). Beachten Sie jedoch, dass die Verwendung der utf8
Zeichensatz in MySQL wird nicht zu 100 % funktionieren.
Tomcat mit Apache
Noch etwas: Wenn Sie Apache + Tomcat + mod_JK Connector verwenden, müssen Sie auch die folgenden Änderungen vornehmen:
- Fügen Sie URIEncoding="UTF-8" in die Datei tomcat server.xml für den 8009-Connector ein, da dieser vom mod_JK-Connector verwendet wird.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- Wechseln Sie in den Apache-Ordner, z. B.
/etc/httpd/conf
und hinzufügen AddDefaultCharset utf-8
sur httpd.conf file
. Anmerkung: Prüfen Sie zunächst, ob sie vorhanden ist oder nicht. Wenn sie existiert, können Sie sie mit dieser Zeile aktualisieren. Sie können diese Zeile auch unten anfügen.