375 votes

Comment faire fonctionner UTF-8 dans les webapps Java?

J'ai besoin d'obtenir de l'UTF-8 dans mon Java de l'application web (servlets + JSP, pas de cadre utilisé) à l'appui d' äöå etc. régulièrement finlandais texte et les alphabets Cyrillique, comme ЦжФ pour les cas particuliers.

Ma configuration est la suivante:

  • Environnement de développement: Windows XP
  • Environnement de Production: Debian

Base de données: MySQL 5.x

Principalement les utilisateurs d'utiliser Firefox2, mais aussi Opera 9.x, FF3, IE7 et Google Chrome sont utilisés pour accéder au site.

Comment atteindre cet objectif?

563voto

kosoant Points 5333

Répondre à moi-même que la FAQ de ce site encourage. Cela fonctionne pour moi:

La plupart des personnages äåö ne sont pas une problématique que le jeu de caractères par défaut utilisé par les navigateurs et tomcat/java pour webapps est latin1 ie. ISO-8859-1, qui "comprend" ces personnages.

Pour obtenir de l'UTF-8 sous Java+Tomcat+Linux/Windows+Mysql requiert les éléments suivants:

La configuration de Tomcat server.xml

Il est nécessaire de configurer le connecteur utilise UTF-8 pour encoder l'url (GET) paramètres:

<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 clé étant URIEncoding="UTF-8" dans l'exemple ci-dessus. Cela garantit que le serveur Tomcat gère tous les paramètres GET comme codé en UTF-8. En conséquence, 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ée comme de l'UTF-8 et il est codé (en général, par le navigateur avant même de faire le serveur) %D0%B6.

Demande POST ne sont pas affectés par cette.

CharsetFilter

Alors il est temps de forcer le java webapp pour traiter toutes les demandes et les réponses codées en UTF-8. Cela implique de définir un ensemble de caractères filtre comme suit:

  package fi.foo.filters;

  import java.io.IOException;
  import javax.servlet.Filter;
  import javax.servlet.FilterChain;
  import javax.servlet.FilterConfig;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;

  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 permet de s'assurer que si le navigateur n'a pas défini le codage utilisé dans la requête, que c'est de l'UTF-8.

L'autre chose qui doit être faite par ce filtre est de définir la valeur par défaut de réponse de l'encodage ie. l'encodage dans lequel le code html renvoyé/tout ce qui est. La solution consiste à définir la réponse de l'encodage etc. dans chaque contrôleur de l'application.

Ce filtre doit être ajouté à la web.xml ou le descripteur de déploiement de l'application web:

 <!--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 la fabrication de ce filtre se trouve à l' tomcat wiki (http://wiki.apache.org/tomcat/Tomcat/UTF-8)

Le codage de la page JSP

Dans votre web.xml, ajoutez la ligne suivante:

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

Alternativement, tous les JSP pages de l'application web aura besoin d'avoir la suite au-dessus d'eux:

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

Si un certain type de mise en page avec les différents JSP-fragments est utilisé, ce qui est nécessaire dans tous les d'entre eux.

HTML-balises meta

JSP le codage de la page indique la JVM pour gérer les caractères dans la page JSP dans le bon encodage. Alors il est temps de dire la vrowser dans lequel l'encodage de la page html:

Ceci est réalisé avec le code suivant 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' />
   ...

JDBC-connexion

Lors de l'utilisation de la base de données, c'est-à-dire que la connexion utilise le codage UTF-8. Ceci est fait dans context.xml ou de l'endroit 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"
    />

MySQL base de données et des tables

La base de données utilisée doit utiliser l'encodage UTF-8. Ce résultat est obtenu par la création de 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 être en UTF-8 aussi:

   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 clé étant CHARSET=utf8.

Configuration du serveur MySQL

MySQL serveri doit être configuré également. Typiquement, cela se fait dans Windows en modifiant mon.ini -file et dans Linux par la configuration de mon.cnf-fichier. Dans ces fichiers, il convient de définir ce que tous les clients connectés au serveur utilise utf8 comme le 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

Mysql procédures et fonctions

Ces également besoin d'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 ;

Les requêtes GET: latin1 et UTF-8

Si et quand il est défini dans tomcat server.xml que OBTENIR les paramètres de la demande sont encodés en UTF-8, OBTENEZ les demandes soient traitées correctement:

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

Parce que des caractères ASCII sont codés de la même manière avec le latin1 et UTF-8, la chaîne "Petteri" est gérée correctement.

Le Cyrillique caractère ж n'est pas comprise dans latin1. Parce que Tomcat est chargé de gérer les paramètres de la demande comme de l'UTF-8 il encode le personnage correctement, comme %D0%B6.

Si et quand les navigateurs sont priés de lire les pages en UTF-8 (avec les en-têtes de requête et html meta-tag), au moins Firefox 2/3 et les autres navigateurs à partir de cette période, tous les encoder les caractères eux-mêmes en tant que %D0%B6.

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

Mais qu'en est äåö?

HTTP-spécification définit que par défaut, les Url sont codées comme latin1. Il en résulte firefox2, firefox3 etc. codant pour la suite

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

dans la version codée

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

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

Le résultat de ceci est que c'est tout à fait impossible pour la webapp pour correly gérer les paramètres de requêtes à partir de requêtes GET comme certains caractères sont codés en latin1 et d'autres en UTF-8. Avis: APRÈS demande de faire un travail que les navigateurs coder tous les paramètres de la requête à partir de formes entièrement en UTF-8 si la page est définie comme étant l'UTF-8

Des trucs à lire

Un très grand merci pour les écrivains de la suite pour donner des réponses à mon problème:

  • http://tagunov.tripod.com/i18n/i18n.html>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 à l'aide de 3 octets de caractères UTF-8. Si vous avez besoin d'aller à l'extérieur de l' (certains alphabets besoin de plus de 3 octets en UTF-8), alors vous devez soit utiliser une saveur d' VARBINARY type de colonne ou de l'utilisation de l' utf8mb4 jeu de caractères (ce qui nécessite MySQL 5.5.3 ou plus tard). Juste être conscient que l'utilisation de l' utf8 ensemble de caractères dans MySQL ne fonctionne pas 100% du temps.

Avec Apache Tomcat

Encore une chose Si vous utilisez Apache + Tomcat + connecteur mod_JK, alors vous aussi besoin de faire les modifications suivantes:

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

14voto

stian Points 1731

Je pense que vous il résume très bien dans votre propre réponse.

Dans le processus de UTF-8-ing(?) de fin à fin, que vous pouvez également vous assurer java lui-même utilise UTF-8. Utilisez - Dfile.encoding=utf-8 en tant que paramètre à la JVM (qui peut être configuré en catalina.bat).

12voto

Raedwald Points 8862

Pour ajouter à réponse de kosoant, si vous utilisez printemps, plutôt que d’écrire votre propre filtre de Servlet, vous pouvez utiliser la classe `` qu’ils fournissent, configurez-le comme suit dans votre fichier web.xml :

1voto

Mike Mountrakis Points 11

Il s’agit de Greek Encoding dans MySql tables quand on veut accéder à l’aide de Java :

Utilisez la configuration de la connexion suivante dans votre pool de connexions de JBoss (mysql-ds.xml)

Si vous ne voulez pas mettre cela dans un pool de connexion JNDI, vous pouvez le configurer comme un url JDBC, comme l’illustre la ligne suivante :

Pour moi et Nick, alors nous ne jamais l’oublier et perdre plus de temps...

1voto

Jay Points 48

Belle réponse détaillée. je voulais juste rajouter une chose de plus qui va certainement aider les autres à voir le codage UTF-8 sur les URLs dans l'action .

Suivez les étapes ci-dessous pour activer le codage UTF-8 sur les Url dans firefox.

  1. tapez "about:config" dans la barre d'adresse.

  2. Utiliser le filtre d'entrée de la recherche pour "réseau.standard-url.encoder-requête-utf8" de la propriété.

  3. les biens ci-dessus seront false par défaut, tour qui de VRAI.
  4. redémarrez le navigateur.

L'encodage UTF-8 sur les Url qui fonctionne par défaut dans IE6/7/8 et google chrome.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X