Question

Je souhaite que UTF-8 fonctionne dans mon application Web Java (servlets + JSP, aucun framework utilisé) pour prendre en charge äöå , etc. code> pour les cas particuliers.

Ma configuration est la suivante:

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

Base de données utilisée: MySQL 5.x

Les utilisateurs utilisent principalement Firefox2 mais utilisent également Opera 9.x, FF3, IE7 et Google Chrome pour accéder au site.

Comment y parvenir?

Était-ce utile?

La solution

Répondez-moi, la FAQ de ce site l'encourage. Cela fonctionne pour moi:

Principalement des caractères & # 228; & # 229; & # 246; ne sont pas problématiques car le jeu de caractères par défaut utilisé par les navigateurs et tomcat / java pour webapps est latin1, à savoir. ISO-8859-1 qui "comprend" ces personnages.

Pour que UTF-8 fonctionne sous Java + Tomcat + Linux / Windows + Mysql, vous devez disposer des éléments suivants:

Configuration du fichier server.xml de Tomcat

Il est nécessaire de configurer le connecteur en utilisant UTF-8 pour coder les paramètres d'URL (demande 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"
/>

L'élément clé étant URIEncoding = "UTF-8" dans l'exemple ci-dessus. Cela garantit que Tomcat gère tous les paramètres GET entrants au format UTF-8 codé. Par conséquent, lorsque l'utilisateur écrit les informations suivantes dans la barre d'adresse du navigateur:

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

le caractère & # 1078; est traité en tant que UTF-8 et est codé en tant que % D0% B6 . (généralement par le navigateur avant même d’avoir accès au serveur).

Les demandes POST ne sont pas concernées par cela.

CharsetFilter

Ensuite, il est temps de forcer l'application Web Java à gérer toutes les demandes et réponses au format UTF-8 codé. Cela nécessite de définir un filtre de jeu de caractères comme suit:

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 vérifie que, si le navigateur n'a pas défini l'encodage utilisé dans la demande, il est défini sur UTF-8.

Ce filtre permet également de définir le codage de la réponse par défaut, c.-à-d. l'encodage dans lequel le html retourné / quel que soit est. L'alternative consiste à définir le codage de la réponse, etc. dans chaque contrôleur de l'application.

Ce filtre doit être ajouté au web.xml ou au 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 de tomcat ( < a href = "http://wiki.apache.org/tomcat/Tomcat/UTF-8" rel = "noreferrer"> http://wiki.apache.org/tomcat/Tomcat/UTF-8 )

Encodage de page JSP

Dans votre web.xml , ajoutez les éléments suivants:

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

Sinon, toutes les pages JSP de l'application Web doivent comporter les éléments suivants en haut:

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

Si un type de présentation avec différents fragments JSP est utilisé, cela est nécessaire dans tous d'entre eux.

balises HTML méta

Le codage de page JSP indique à la machine virtuelle Java de gérer les caractères de la page JSP avec le codage correct. Ensuite, il est temps d'indiquer au navigateur dans lequel l'encodage de la page html est:

Ceci est effectué avec les éléments suivants en haut de chaque page xhtml générée par l'application Web:

   <?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

Si vous utilisez une base de données, vous devez définir que la connexion utilise le codage UTF-8. Cela se fait dans context.xml ou partout où la connexion JDBC est défectueuse 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 MySQL et tables

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 être en UTF-8 également:

   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;

L'élément clé étant CHARSET = utf8 .

Configuration du serveur MySQL

Le serveur MySQL doit également être configuré. Cela se fait généralement sous Windows en modifiant le fichier my.ini , et sous Linux en configurant le fichier my.cnf . Dans ces fichiers, vous devez définir 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

Celles-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 codés en UTF-8, les requêtes GET suivantes sont géré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 codés de la même manière avec latin1 et UTF-8, la chaîne "Petteri" est géré correctement.

Le caractère cyrillique & # 1078; 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 code correctement ce caractère sous la forme % D0% B6 .

Si et quand les navigateurs sont invités à lire les pages en codage 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 codent tous le caractère comme % D0% B6 .

Le résultat final est que tous les utilisateurs portant le nom "Petteri" sont trouvés, ainsi que tous les utilisateurs portant le nom " & # 1078; " sont trouvés.

Mais qu'en est-il de & # 228; & # 229; & # 246;?

La spécification HTTP définit que, par défaut, les URL sont codées comme latin1. Ceci a pour conséquence que firefox2, firefox3, etc. encodent les

    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 & # 228; est codé sous la forme % E4 . Même si la page / request / tout est défini pour utiliser UTF-8 . La version codée UTF-8 de & # 228; est % C3% A4

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

Éléments à 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 à 3 octets. Si vous devez aller en dehors de cela (certains alphabets requièrent plus de 3 octets de UTF-8), vous devez utiliser une sorte de type de colonne VARBINARY ou utiliser le utf8mb4 jeu de caractères (qui requiert MySQL 5.5.3 ou plus tard). Sachez simplement qu'utiliser le jeu de caractères utf8 dans MySQL ne fonctionnera pas dans 100% des cas.

Tomcat avec Apache

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

  1. Ajouter URIEncoding = "UTF-8" dans le fichier tomcat server.xml pour le connecteur 8009, il est utilisé par le connecteur mod_JK. < Port du connecteur = " 8009 " protocole = " AJP / 1.3 " redirectPort = " 8443 " URIEncoding = "UTF-8" / >
  2. Accédez à votre dossier Apache, à savoir / etc / httpd / conf et ajoutez AddDefaultCharset utf-8 dans le fichier httpd.conf . 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.

Autres conseils

Je pense que vous avez bien résumé la situation dans votre propre réponse.

Lors du processus UTF-8-ing (?) de bout en bout, vous pouvez également vous assurer que Java lui-même utilise UTF-8. Utilisez -Dfile.encoding = utf-8 en tant que paramètre de la machine virtuelle Java (peut être configuré dans catalina.bat).

Pour ajouter à la réponse de kosoant , si vous utilisez Spring, plutôt que d'écrire votre propre filtre de servlet, vous pouvez utiliser la classe org.springframework.web.filter.CharacterEncodingFilter qu’elle fournit, en la configurant comme suit dans votre web.xml:

 <filter>
    <filter-name>encoding-filter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
       <param-name>encoding</param-name>
       <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
       <param-name>forceEncoding</param-name>
       <param-value>FALSE</param-value>
    </init-param>
 </filter>
 <filter-mapping>
    <filter-name>encoding-filter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

Je souhaite également ajouter, à partir de ici , cette partie a résolu mon problème avec Utf:

runtime.encoding=<encoding>

Ceci est pour le codage grec dans les tables MySql lorsque nous voulons y accéder en utilisant Java:

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

<connection-url>jdbc:mysql://192.168.10.123:3308/mydatabase</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>nts</user-name>
<password>xaxaxa!</password>
<connection-property name="useUnicode">true</connection-property>
<connection-property name="characterEncoding">greek</connection-property>

Si vous ne souhaitez pas placer ceci dans un pool de connexions JNDI, vous pouvez le configurer comme une url JDBC, comme l'illustre la ligne suivante:

jdbc:mysql://192.168.10.123:3308/mydatabase?characterEncoding=greek

Pour moi et Nick, nous ne l'oublions jamais et nous ne perdons plus de temps .....

Belle réponse détaillée. je voulais juste ajouter une dernière chose qui aidera certainement les autres à voir l'encodage UTF-8 sur les URL en action.

Suivez les étapes ci-dessous pour activer le codage UTF-8 sur les URL de Firefox.

  1. type "à propos de: config" dans la barre d'adresse.

  2. Utilisez le type d’entrée de filtre pour rechercher "network.standard-url.encode-query-utf8". propriété.

  3. la propriété ci-dessus sera false par défaut, mettez-la à TRUE.
  4. redémarrez le navigateur.

Le codage UTF-8 sur les URL fonctionne par défaut dans IE6 / 7/8 et chrome.

J'ai un problème similaire, mais, dans les noms de fichier d'un fichier, je compresse avec apache commons. Donc, je l'ai résolu avec cette commande:

convmv --notest -f cp1252 -t utf8 * -r

cela fonctionne très bien pour moi. J'espère que ça aidera n'importe qui;)

En ce qui concerne l'affichage de caractères Unicode à partir de liasses de messages, je n'ai pas besoin d'appliquer le "codage de page JSP". section pour afficher Unicode sur ma page jsp. Tout ce dont j'ai besoin, c'est "CharsetFilter". section.

Un autre point qui n’a pas été mentionné concerne les servlets Java travaillant avec Ajax. J'ai des situations où une page Web récupère le texte utf-8 de l'utilisateur l'envoyant dans un fichier JavaScript qui l'inclut dans un URI envoyé au Servlet. Le servlet interroge une base de données, capture le résultat et le renvoie sous forme XML au fichier JavaScript qui le formate et insère la réponse formatée dans la page Web d'origine.

Dans une application Web, je suivais les instructions d'un livre Ajax ancien pour intégrer le code JavaScript dans la construction de l'URI. L'exemple du livre utilise la méthode escape (), que j'ai découverte (à la dure) est fausse. Pour utf-8, vous devez utiliser encodeURIComponent ().

Peu de gens semblent avoir leur propre Ajax ces jours-ci, mais je pensais que je pourrais aussi bien ajouter ceci.

À propos de CharsetFilter mentionné dans la réponse @kosoant ....

Il existe une construction dans Filtre dans tomcat web.xml (situé dans conf / web.xml ). Le filtre est nommé setCharacterEncodingFilter et est commenté par défaut. Vous pouvez supprimer le commentaire (rappelez-vous également de son filtrage-mappage )

.

De plus, il n'est pas nécessaire de définir jsp-config dans votre web.xml (je l'ai testé pour Tomcat 7+)

Vous pourrez parfois résoudre le problème grâce à l’assistant administrateur de MySQL. Dans

  

Variables de démarrage > Avancé >

et définissez Def. Jeu de caractères: utf8

Peut-être que cette configuration nécessite de redémarrer MySQL.

Les réponses précédentes ne fonctionnaient pas avec mon problème. Ce n'était qu'en production, avec tomcat et apache mod_proxy_ajp. Les corps non postés ont-ils été perdus? Le problème était finalement avec JVM defaultCharset (US-ASCII dans une installation par défaut: Charset dfset = Charset.defaultCharset ();) La solution a donc été exécutée sur un serveur tomcat avec un modificateur pour exécuter la machine virtuelle Java avec UTF-8 en tant que jeu de caractères par défaut:

JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8" 

(ajoutez cette ligne à catalina.sh et au service tomcat restart)

Peut-être devez-vous aussi changer la variable système linux (éditez les fichiers ~ / .bashrc et ~ / .profile pour une modification permanente, voir https://perlgeek.de/en/article/set-up-a-clean-utf8-environment )

  

exportation LC_ALL = en_US.UTF-8
  exportation LANG = en_US.UTF-8

     

exportation LANGUAGE = en_US.UTF-8

Face au même problème sur Spring MVC 5 + Tomcat 9 + JSP.
Après de longues recherches, une solution élégante a été trouvée ( non besoin de filtres et non besoin de modifications dans Tomcat < strong> server.xml (à partir de la version 8.0.0-RC3))

  1. Dans l'implémentation WebMvcConfigurer, définissez le codage par défaut pour messageSource (pour la lecture de données à partir de fichiers sources de messages dans le codage UTF-8.

    .
    @Configuration
    @EnableWebMvc
    @ComponentScan("{package.with.components}")
    public class WebApplicationContextConfig implements WebMvcConfigurer {
    
        @Bean
        public MessageSource messageSource() {
            final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    
            messageSource.setBasenames("messages");
            messageSource.setDefaultEncoding("UTF-8");
    
            return messageSource;
        }
    
        /* other beans and methods */
    
    }
    
  2. Dans l'implémentation DispatcherServletInitializer, @Override la méthode onStartup et définissez-y le codage des caractères de requête et de ressource.

    public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        public void onStartup(final ServletContext servletContext) throws ServletException {
    
            // https://wiki.apache.org/tomcat/FAQ/CharacterEncoding
            servletContext.setRequestCharacterEncoding("UTF-8");
            servletContext.setResponseCharacterEncoding("UTF-8");
    
            super.onStartup(servletContext);
        }
    
        /* servlet mappings, root and web application configs, other methods */
    
    }
    
  3. Enregistrez toutes les sources de messages et affichez les fichiers au format UTF-8.

  4. Ajoutez <% @ page contentType = & text; html; charset = UTF-8 " % > ou <% @ page pageEncoding = & UTF-8 " % > dans chaque fichier * .jsp ou , ajoutez un descripteur jsp-config dans web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     id="WebApp_ID" version="3.0">
        <display-name>AppName</display-name>
    
        <jsp-config>
            <jsp-property-group>
                <url-pattern>*.jsp</url-pattern>
                <page-encoding>UTF-8</page-encoding>
            </jsp-property-group>
        </jsp-config>
    </web-app>
    

Si vous avez spécifié dans le pool de connexions (mysql-ds.xml), dans votre code Java, vous pouvez ouvrir la connexion comme suit:

DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://192.168.1.12:3308/mydb?characterEncoding=greek",
    "Myuser", "mypass");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top