Après plusieurs heures passées à trouver mon erreur d'encodage UTF-8, voici un petite liste des points à vérifier sur une application web.
Mon environnement :
- MySQL
- Hibernate
- Spring MVC
- Velocity (pour les mails)
- Tomcat
MySQL
Vérifier que les tables et les champs textes utilisent le charset UTF-8 :
CREATE TABLE [...] DEFAULT CHARSET=utf8;
Hibernate
-- hibernate.cfg.xml --
<hibernate-configuration> <session-factory> <property name="hibernate.connection.useUnicode">true</property> <property name="hibernate.connection.characterEncoding">utf-8</property> </session-factory> </hibernate-configuration>
Spring framework
Utiliser le servlet filter CharacterEncodingFilter
dans le web.xml afin de forcer l'encodage. Attention de bien positionner ce filtre en première position dans la liste des différents filtres!
-- web.xml --
<web-app> <filter> <filter-name>encodingFilter</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>true</param-value> </init-param> </filter> </web-app>
Velocity et mails
Lors du load des templates Velocity, spécifier l'encodage UTF-8.
String content = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, fileName, "UTF-8", tokens);
Encoder aussi les mails. Dans mon cas avec MimeMessageHelper
.
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
JSP
Définir l'encodage des JSP.
<%@ page contentType="text/html; charset=UTF-8"%> <%@ page pageEncoding="UTF-8"%>
Tomcat
Si après tout ça vous avez encore des problèmes, vous pouvez toujours essayer de configurer Tomcat mais je pense que ça ne changera pas grand chose...
-- server.xml --
<Server> <Service> <Connector URIEncoding="UTF-8" useBodyEncodingForURI="true" [...] /> </Service> </Server>
Conclusion
Tous ces points ne sont surement pas nécessaire... il faut que je vérifie. Je pense que l'encodage au niveau de la base de données, du web.xml et des mails (Velocity et MimeMessage) est suffisant mais cette liste peut ammener des indices à d'autres qui rencontrent ce genre de problèmes...
Dans mon cas, le problème venait du servlet filter d'encodage de Spring : il n'était pas en première position :-(
12 commentaires:
Dans un servlet context pour faire du jdbc direct, j'ai déjà eu besoin d'avoir un URL funky comme ça:
jdbc:mysql://localhost/zoum3?useUnicode=true&characterEncoding=utf8&useOldUTF8Behavior=true
Si l'on fait du build avec Maven 2, il faut penser à rajouter ceci :
http://maven.apache.org/plugins/maven-resources-plugin/examples/encoding.html
Autre possibilité pour tomcat, toujours au niveau de la balise Connector, utiliser l'attribut useBodyEncodingForURI.
Ceci permet d'avoir certaines pages en UTF-8 d'autre non (pratique pendant une phase de migration sur une grosse webapp ou on est pas sûre d'avoir tout changé).
Et pour les servlets, autre possibilité qui ne nécéssite pas de modifier le web.xml, mettre ça dans le code (doGet) :
request.setCharacterEncoding("UTF-8");
Et pour passer toute la JVM en UTF-8 par défaut, il suffit d'ajouter :
-Dfile.encoding=UTF-8
à la ligne de lancement de Tomcat par exemple (pratique aussi).
Ne pas oublier le filter-mapping...
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Précision à propos de Tomcat : Il est suggéré la ligne suivante :
<Connector URIEncoding="UTF-8" useBodyEncodingForURI="true" [...] />
Cette instruction concerne l'encodage des URL (qui peuvent contenir des accents, ex : http://fr.wikipedia.org/wiki/%C3%89t%C3%A9).
Cette URL est encodée en UTF-8 (%C3%89 correspond à 'é'). Pour Tomcat, l'encodage par défaut est l'ISO-8859-1. Il est donc nécessaire de préciser useBodyEncodingForURI="true".
Cela fait que l'URL a le même encodage que le corps de la page. (qui peut être défini par servletRequest.setCharacterEncoding("UTF-8"); dans la méthode doPost).
Attention, avec l'option de JVM -Dfile.encoding=UTF-8 au lancement de Tomcat, toutes les applications héritent de cet encodage. Ce qui empêche le déploiement d'applications fonctionnant en "ISO Latin 1".
Eclipse
-------
Il s'agit de gérer les ressouces fichiers du projet en mode UTF-8. Depuis
le menu Window, Preferences :
General, Editors, Text Editors, Spelling, Dictionaries, Encoding : UTF-8
General, Workspaces, Text file encoding : UTF-8
General, Content Types : tout passer en UTF-8
Et aussi :
http://support.jalios.com/jcms/jx_21247/jcms-55-utf-8
je ne peux pas m'empecher de vous ecrire enfin de vous remercier pour ce cadeau.Franchement j'ai galeré avant de trouver cette solution.
il m'a suffit juste d'ajoute
URIEncoding="UTF-8"
useBodyEncodingForURI="true"
et tout marche bien
Bravo pour l'option du Connector Tomcat pour les formulaire soumis en GET.
j'ai galéré 3 h avant de trouver
Spring : Gestion du message source suite soucis utf-8 + tot utiliser :
<bean id="messageSource";
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
avec un fichier messages.properties encodé en utf-8
Publier un commentaire