Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment faire fonctionner UTF-8 dans les applications Web Java ?

Me répondre comme la FAQ de ce site l'encourage. Cela fonctionne pour moi :

La plupart du temps, les caractères äåö ne posent pas de problème car le jeu de caractères par défaut utilisé par les navigateurs et tomcat/java pour les applications Web est latin1, c'est-à-dire. ISO-8859-1 qui "comprend" ces caractères.

Pour faire fonctionner UTF-8 sous Java+Tomcat+Linux/Windows+Mysql, il faut ce qui suit :

Configuration du fichier server.xml de Tomcat

Il est nécessaire de configurer que le connecteur utilise UTF-8 pour encoder les paramètres d'url (requête GET) :

<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"
/>

La partie clé étant URIEncoding="UTF-8" dans l'exemple ci-dessus. Cela garantit que Tomcat gère tous les paramètres GET entrants encodés en UTF-8. Par conséquent, lorsque l'utilisateur écrit ce qui suit dans la barre d'adresse du navigateur :

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

le caractère Ö est traité en UTF-8 et est encodé (généralement par le navigateur avant même d'accéder au serveur) sous la forme %D0%B6 .

Les requêtes POST ne sont pas affectées par cela.

FiltreCharset

Ensuite, il est temps de forcer l'application Web Java à gérer toutes les demandes et réponses encodées en UTF-8. Cela nécessite que nous définissions un filtre de jeu de caractères comme celui-ci :

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() {
    }
}

Ce filtre s'assure que si le navigateur n'a pas défini l'encodage utilisé dans la requête, il est défini sur UTF-8.

L'autre chose faite par ce filtre est de définir le codage de réponse par défaut, c'est-à-dire. l'encodage dans lequel le html retourné/quel qu'il soit. L'alternative consiste à définir le codage de réponse, etc. dans chaque contrôleur de l'application.

Ce filtre doit être ajouté au web.xml ou le descripteur de déploiement de la 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>

Les instructions pour créer ce filtre se trouvent sur le wiki Tomcat ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )

Encodage des pages JSP

Dans votre web.xml , ajoutez ce qui suit :

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>
</jsp-config>

Alternativement, toutes les pages JSP de l'application Web devraient avoir ce qui suit en haut :

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

Si une sorte de mise en page avec différents fragments JSP est utilisée, alors cela est nécessaire dans tous d'entre eux.

Balises méta HTML

L'encodage de page JSP indique à la JVM de gérer les caractères de la page JSP dans l'encodage correct. Ensuite, il est temps d'indiquer au navigateur dans quel encodage se trouve la page html :

Cela se fait avec ce qui suit en haut de chaque page xhtml produite par la webapp :

   <?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' />
   ...

Connexion JDBC

Lors de l'utilisation d'une base de données, il doit être défini que la connexion utilise le codage UTF-8. Cela se fait dans context.xml ou partout où la connexion JDBC est définie comme suit :

      <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"
    />

Base de données et tables MySQL

La base de données utilisée doit utiliser le codage UTF-8. Ceci est réalisé en créant la base de données avec les éléments suivants :

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

Ensuite, toutes les tables doivent également être en UTF-8 :

   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;

La partie clé étant CHARSET=utf8 .

Configuration du serveur MySQL

Le serveur MySQLi doit également être configuré. Généralement, cela se fait sous Windows en modifiant my.ini -file et sous Linux en configurant my.cnf -file.Dans ces fichiers, il doit être défini que tous les clients connectés au serveur utilisent utf8 comme jeu de caractères par défaut et que le jeu de caractères par défaut utilisé par le serveur est également utf8.

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

   [mysql]
   default-character-set=utf8

Procédures et fonctions MySQL

Ceux-ci doivent également avoir le jeu de caractères défini. Par exemple :

   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 ;

Requêtes GET :latin1 et UTF-8

Si et quand il est défini dans le fichier server.xml de tomcat que les paramètres de requête GET sont encodés en UTF-8, les requêtes GET suivantes sont traitées correctement :

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

Étant donné que les caractères ASCII sont encodés de la même manière avec latin1 et UTF-8, la chaîne "Petteri" est gérée correctement.

Le caractère cyrillique ж n'est pas du tout compris en latin1. Étant donné que Tomcat est chargé de gérer les paramètres de requête en UTF-8, il encode correctement ce caractère en tant que %D0%B6 .

Si et quand les navigateurs sont invités à lire les pages en encodage UTF-8 (avec en-têtes de requête et balise méta html), au moins Firefox 2/3 et les autres navigateurs de cette période encodent tous le caractère eux-mêmes en tant que %D0% B6 .

Le résultat final est que tous les utilisateurs avec le nom "Petteri" sont trouvés et aussi tous les utilisateurs avec le nom "ж" sont trouvés.

Mais qu'en est-il de äåö ?

La spécification HTTP définit que, par défaut, les URL sont encodées en latin1. Cela se traduit par firefox2, firefox3 etc. encodant les éléments suivants

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

dans la version encodée

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

En latin1 le caractère ä est codé comme %E4 . Même si la page/la requête/tout est défini pour utiliser UTF-8 . La version encodée en UTF-8 de ä est %C3%A4

Le résultat est qu'il est tout à fait impossible pour l'application Web de gérer correctement les paramètres de requête des requêtes GET car certains caractères sont encodés en latin1 et d'autres en UTF-8.Remarque :les requêtes POST fonctionnent car les navigateurs encodent tous les paramètres de requête à partir de formulaires entièrement en UTF-8 si la page est définie comme étant UTF-8

Choses à lire

Un très grand merci aux rédacteurs de ce qui suit pour avoir répondu à mon problème :

  • 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/

Remarque importante

prend en charge le plan multilingue de base utilisant des caractères UTF-8 de 3 octets. Si vous devez aller au-delà de cela (certains alphabets nécessitent plus de 3 octets d'UTF-8), vous devez soit utiliser une variante de VARBINARY type de colonne ou utilisez le utf8mb4 jeu de caractères (qui nécessite MySQL 5.5.3 ou ultérieur). Sachez simplement qu'en utilisant le utf8 jeu de caractères dans MySQL ne fonctionnera pas 100 % du temps.

Tomcat avec Apache

Encore une chose Si vous utilisez le connecteur Apache + Tomcat + mod_JK, vous devez également effectuer les modifications suivantes :

  1. Ajoutez URIEncoding="UTF-8" dans le fichier tomcat server.xml pour le connecteur 8009, il est utilisé par le connecteur mod_JK. <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
  2. Allez dans votre dossier apache, c'est-à-dire /etc/httpd/conf et ajoutez AddDefaultCharset utf-8 dans le httpd.conf file . Remarque : Vérifiez d'abord qu'il existe ou non. S'il existe, vous pouvez le mettre à jour avec cette ligne. Vous pouvez également ajouter cette ligne en bas.