Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie bekomme ich UTF-8 in Java-Webapps zum Laufen?

Beantworte mich selbst, wie die FAQ dieser Seite dazu ermutigt. Das funktioniert bei mir:

Meistens sind die Zeichen äåö kein Problem, da der von Browsern und Tomcat/Java für Webapps verwendete Standardzeichensatz latin1 ist, dh. ISO-8859-1, das diese Zeichen "versteht".

Damit UTF-8 unter Java+Tomcat+Linux/Windows+Mysql funktioniert, ist Folgendes erforderlich:

Server.xml von Tomcat konfigurieren

Es muss konfiguriert werden, dass der Connector UTF-8 verwendet, um URL-Parameter (GET-Anfrage) 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. Dadurch wird sichergestellt, dass Tomcat alle eingehenden GET-Parameter als UTF-8-codiert behandelt. Als Ergebnis schreibt der Benutzer Folgendes in die Adressleiste des Browsers:

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

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

POST-Anfragen sind davon nicht betroffen.

Zeichensatzfilter

Dann ist es an der Zeit, die Java-Webanwendung zu zwingen, alle Anfragen und Antworten als UTF-8-codiert zu verarbeiten. 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 festgelegt hat, diese auf UTF-8 festgelegt ist.

Die andere Sache, die dieser Filter macht, ist das Festlegen der Standard-Antwortcodierung, dh. 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 web.xml hinzugefügt werden oder der Bereitstellungsdeskriptor der Webanwendung:

 <!--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-Seitenkodierung

In Ihrer 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 müssten alle JSP-Seiten der Webapp oben Folgendes haben:

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

Wenn irgendeine Art von Layout mit verschiedenen JSP-Fragmenten verwendet wird, dann wird dies alle benötigt von ihnen.

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 an der Zeit, dem Browser mitzuteilen, in welcher Codierung die HTML-Seite vorliegt:

Dies geschieht mit dem Folgenden oben auf jeder xhtml-Seite, die von der Webanwendung erstellt 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">
   <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 db muss definiert werden, dass die Verbindung UTF-8-Kodierung verwendet. Dies erfolgt in context.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&amp;characterEncoding=UTF-8"
    />

MySQL-Datenbank und -Tabellen

Die verwendete Datenbank muss die UTF-8-Kodierung verwenden. Dies wird erreicht, indem die Datenbank folgendermaßen erstellt wird:

   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 Schlüsselteil ist CHARSET=utf8 .

MySQL-Serverkonfiguration

MySQL serveri muss ebenfalls konfiguriert werden. Normalerweise geschieht dies in Windows durch Modifizieren von my.ini -Datei und unter Linux durch die Konfiguration von my.cnf -file.In diesen Dateien sollte definiert 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

Falls und wenn in Tomcats server.xml definiert ist, dass GET-Anforderungsparameter in UTF-8 kodiert 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 gleich kodiert werden, wird der String "Petteri" korrekt behandelt.

Das kyrillische Zeichen Ö wird im Lateinischen überhaupt nicht verstanden1. Da Tomcat angewiesen wird, Anforderungsparameter als UTF-8 zu verarbeiten, codiert es dieses Zeichen korrekt als %D0%B6 .

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 alle 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. Folgendes 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 das Zeichen ä ist als %E4 kodiert . Obwohl die Seite/Anfrage/alles für die Verwendung von UTF-8 definiert ist . Die UTF-8-kodierte Version von ä ist %C3%A4

Das Ergebnis davon ist, dass es für die Webapp ziemlich unmöglich ist, die Anforderungsparameter von GET-Anforderungen korrekt zu verarbeiten, da einige Zeichen in latin1 und andere in UTF-8 codiert sind.Hinweis:POST-Anforderungen funktionieren, da Browser alle Anforderungsparameter codieren von Formularen vollständig in UTF-8, wenn die Seite als UTF-8 definiert ist

Lesestoff

Ein sehr großes Dankeschön an die Verfasser der folgenden Zeilen 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/

Wichtiger Hinweis

unterstützt das Basic Multilingual Plane mit 3-Byte-UTF-8-Zeichen. Wenn Sie darüber hinausgehen müssen (bestimmte Alphabete erfordern mehr als 3 Bytes UTF-8), müssen Sie entweder eine Variante von VARBINARY verwenden Spaltentyp oder verwenden Sie den utf8mb4 Zeichensatz (was MySQL 5.5.3 oder höher erfordert). Beachten Sie nur, dass die Verwendung von utf8 Zeichensatz in MySQL wird nicht 100% der Zeit funktionieren.

Tomcat mit Apache

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

  1. Fügen Sie URIEncoding="UTF-8" in die Tomcat server.xml-Datei für den 8009-Connector hinzu, sie wird vom mod_JK-Connector verwendet. <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
  2. Gehen Sie in Ihren Apache-Ordner, z. B. /etc/httpd/conf und fügen Sie AddDefaultCharset utf-8 hinzu in der httpd.conf file . Hinweis: Überprüfen Sie zuerst, 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.