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

Je dois faire fonctionner UTF-8 dans mon webapp Java (servlets + JSP, pas de framework utilisé) pour supporter äöå etc. pour le texte finnois standard et les alphabets cyrilliques comme ЦжФ 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 aussi Opera 9.x, FF3, IE7 et Google Chrome sont utilisés pour accéder au site.

Comment y parvenir?

En me répondant 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.-à-d. ISO-8859-1 qui “comprend” ces caractères.

Pour que UTF-8 fonctionne sous Java + Tomcat + Linux / Windows + Mysql, il faut:

Configuration de server.xml de Tomcat

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

  

La partie clé étant URIEncoding = “UTF-8” dans l’exemple ci-dessus. Cela garantit que Tomcat gère tous les parameters GET entrants au format 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 géré comme UTF-8 et est encodé dans (généralement par le navigateur avant même d’accéder au serveur) en % D0% B6 .

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

CharsetFilter

Ensuite, il est temps de forcer l’application Web Java à gérer toutes les requêtes et les réponses au format UTF-8. Cela nécessite que nous définissions 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 Ssortingng 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 l’encodage de la réponse par défaut, c.-à-d. l’encodage dans lequel le HTML retourné / quoi que ce 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 fichier web.xml ou au descripteur de déploiement de l’application Web:

    CharsetFilter fi.foo.filters.CharsetFilter  requestEncoding UTF-8    CharsetFilter /*  

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

JSP encodage de page

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

   *.jsp UTF-8   

Autrement, toutes les pages JSP de l’application Web devraient comporter les éléments suivants:

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

Si une disposition avec différents fragments JSP est utilisée, cela est nécessaire dans tous .

Balises meta-HTML

Le codage de page JSP indique à la JVM de gérer les caractères de la page JSP dans le bon codage. Ensuite, il est temps de dire au navigateur dans quel encodage la page html est:

Cela se fait avec les éléments suivants en haut de chaque page xhtml produite par l’application Web:

       ... 

Connexion JDBC

Lorsque vous utilisez une firebase database, 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éfinie comme suit:

   

Base de données et tables MySQL

La firebase database utilisée doit utiliser le codage UTF-8. Ceci est réalisé en créant la firebase database 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; 

La partie clé étant CHARSET = utf8 .

Configuration du serveur MySQL

MySQL serveri doit également être configuré. En général, cela se fait sous Windows en modifiant le fichier my.ini et sous Linux en configurant my.cnf -file. Dans ces fichiers, il convient de 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

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 parameters de requête GET sont encodé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=ж 

Comme 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ée correctement.

Le caractère cyrillique ж n’est pas du tout compris en latin1. Étant donné que Tomcat est chargé de gérer les parameters de demande comme 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 les en-têtes de requête et la méta-étiquette html), au moins Firefox 2/3 et les autres navigateurs de cette période codent tous le caractère % D0% B6 .

Le résultat final est que tous les utilisateurs avec le nom “Petteri” sont trouvés et 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 codées en latin1. Cela se traduit par firefox2, firefox3 etc.

  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 encodé en % E4 . Même si la page / request / everything est définie pour utiliser UTF-8 . La version codée 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 parameters 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 parameters de requête à partir de formulaires complètement dans UTF-8 si la page est définie comme étant UTF-8

Des choses à lire

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

Note importante

mysql prend en charge le plan multilingue de base en utilisant des caractères UTF-8 de 3 octets. Si vous devez sortir de cela (certains alphabets requièrent plus de 3 octets de UTF-8), vous devez soit utiliser un type de colonne VARBINARY , soit utiliser le utf8mb4 caractères utf8mb4 (qui nécessite MySQL 5.5.3 ou une version ultérieure). ). Sachez que l’utilisation du jeu de caractères utf8 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.
  2. Accédez à votre dossier Apache, à savoir /etc/httpd/conf et ajoutez AddDefaultCharset utf-8 dans le httpd.conf file . Remarque: vérifiez d’abord s’il existe ou non. S’il existe, vous pouvez le mettre à jour avec cette ligne. Vous pouvez également append cette ligne en bas.

Je pense que vous avez très bien résumé votre réponse.

Dans le processus de UTF-8-ing (?) De bout en bout, vous pouvez également vous assurer que Java utilise UTF-8. Utilisez -Dfile.encoding = utf-8 comme paramètre pour la JVM (peut être configuré dans catalina.bat).

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

   encoding-filter org.springframework.web.filter.CharacterEncodingFilter  encoding UTF-8   forceEncoding FALSE    encoding-filter /*  

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)

 jdbc:mysql://192.168.10.123:3308/mydatabase com.mysql.jdbc.Driver nts xaxaxa! true greek 

Si vous ne voulez pas mettre cela dans un pool de connexions JNDI, vous pouvez le configurer comme une URL JDBC comme le montre la ligne suivante:

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

Pour moi et Nick, alors on ne l’oublie jamais et on perd plus de temps …..

Belle réponse détaillée. Je voulais juste append une 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. tapez “about: config” dans la barre d’adresse.

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

  3. La propriété ci-dessus sera fausse par défaut, transformez-la en TRUE.
  4. redémarrez le navigateur.

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

Je veux aussi append d’ ici que cette partie a résolu mon problème d’utf:

 runtime.encoding= 

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

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

ça marche très bien pour moi. J’espère que ça aidera quelqu’un;)

Pour mon cas d’affichage de caractères Unicode à partir d’ensembles de messages, je n’ai pas besoin d’appliquer la section “Encodage de page JSP” pour afficher Unicode sur ma page jsp. Tout ce dont j’ai besoin est la section “CharsetFilter”.

Un autre point qui n’a pas été mentionné concerne les Java Servlets travaillant avec Ajax. Dans certaines situations, une page Web récupère le texte utf-8 de l’utilisateur qui l’envoie vers un fichier JavaScript qui l’inclut dans un URI envoyé à la Servlet. La servlet interroge une firebase database, capture le résultat et le renvoie au format XML dans le 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 premières instructions du livre Ajax pour terminer le code JavaScript lors de la construction de l’URI. L’exemple dans le livre a utilisé la méthode escape (), que j’ai découvert (à la dure) est faux. Pour utf-8, vous devez utiliser encodeURIComponent ().

Peu de gens semblent lancer leur propre Ajax ces jours-ci, mais j’ai pensé que je pourrais aussi bien append ceci.

A propos de CharsetFilter mentionné dans @kosoant answer ….

Il existe un Filter intégré dans tomcat web.xml (situé à conf/web.xml ). Le filtre s’appelle setCharacterEncodingFilter et est commenté par défaut. Vous pouvez le décommenter (n’oubliez pas de supprimer la mise en commentaire de son filter-mapping )

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

Quelque temps, vous pouvez résoudre le problème via l’assistant MySQL Administrator. Dans

Variables de démarrage> Avancé>

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

Peut-être que cette configuration doit redémarrer MySQL.

Les réponses précédentes ne fonctionnaient pas avec mon problème. C’était seulement en production, avec tomcat et apache mod_proxy_ajp. Le corps de la poste a perdu des caractères non ascii par? Le problème a finalement été avec JVM defaultCharset (US-ASCII dans une installation par défaut: Charset dfset = Charset.defaultCharset ();) donc, la solution a été exécutée sur le serveur tomcat avec un modificateur pour exécuter la JVM avec UTF-8 comme 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 (edit ~ / .bashrc et ~ / .profile pour un changement permanent, voir https://perlgeek.de/en/article/set-up-a-clean-utf8-environment )

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

exporter LANGUAGE = en_US.UTF-8

Si vous avez spécifié dans le pool de connexion (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");