Les bonnes pratiques avec Struts – afficher les formulaires en UTF-8
Voici un troisième billet dans la série sur Les bonnes pratiques avec Struts.
Sommaire
Introduction
A partir du moment où une application doit être internationalisée, il est intéressant d’utiliser l’encodage UTF-8 par défaut. Dès lors, un problème d’affichage des valeurs des formulaires se pose avec certains caractères[1].
Solutions
Il existe deux solutions courantes pour répondre à ce problème, qui s’implémentent :
- dans les méthodes
reset()
etvalidate()
de la classeActionForm
- avec des filtres des servlets
ActionForm.reset & ActionForm.validate
Il suffit simplement d’implémenter ces deux méthodes dans tous vos ActionForm
:
public void reset(ActionMapping mapping, HttpServletRequest request) { try { request.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } super.reset(mapping, request); } public void validate(ActionMapping mapping, HttpServletRequest request) { try { request.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } super.validate(mapping, request); }
Cette méthode fonctionne bien. Mais elle pose deux problèmes :
- Il faut implémenter ces méthodes dans tous les
ActionForm
. Ce problème peut être contourné par l’implémentation d’une classe de baseBaseActionForm
. - Le comportement des
DynaActionForm
n’est pas impacté par cette astuce.
Filtres de servlet
Il faut écrire un filtre de servlet qui va modifier l’encodage de toutes les requêtes :
import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class EncodingFilter implements javax.servlet.Filter { private String encoding; public void init(FilterConfig filterConfig) throws ServletException { this.encoding = filterConfig.getInitParameter("encoding"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { request.setCharacterEncoding(encoding); filterChain.doFilter(request, response); } public void destroy() { } }
Ensuite, il faut déclarer le filtre dans le fichier /WEB-INF/web.xml
ainsi (avant tous les autres filtres) :
<filter> <filter-name>Encoding Filter</filter-name> <filter-class>EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Encoding Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Maintenant toutes les requêtes sont correctement lues avec l’encodage UTF-8.
Conclusion
La seconde solution est non-intrusive et plus sûre. De plus, elle n’est pas spécifique à Struts et peut être utilisée pour n’importe quel type d’application web J2EE.
Il ne reste plus qu’à traduire vos applications en chinois. 😀
Notes
[1] Comme les caractères accentués tels que é, è, à, ô, …
https://blog.lecacheur.com/2006/08/31/les-bonnes-pratiques-avec-struts-afficher-les-formulaires-en-utf-8/DéveloppementStrutsstrutsVoici un troisième billet dans la série sur Les bonnes pratiques avec Struts. Introduction A partir du moment où une application doit être internationalisée, il est intéressant d'utiliser l'encodage UTF-8 par défaut. Dès lors, un problème d'affichage des valeurs des formulaires se pose avec certains caractères. Solutions Il existe deux solutions courantes pour...SeBSébastien LECACHEUR23r0@laposte.netAdministratorLe weblogue de SeB
Merci beaucoup seb pour ce post, car grâce à celui-ci, je viens de résoudre mon problème d’encoding sur lequel j’ai passé plus de 8h!!
Content de savoir que ce billet a pu t’aider ! C’est vrai que la solution n’est pas évidente à trouver. Je suis étonné que Struts ne détecte pas automatiquement l’encodage des données des formulaires…
bonjour
j ai ce probleme la
java.lang.NullPointerException: charsetName
java.lang.String.(Unknown Source)
java.lang.String.(Unknown Source)
org.apache.catalina.connector.Request.setCharacterEncoding(Request.java:1427)
org.apache.catalina.connector.RequestFacade.setCharacterEncoding(RequestFacade.java:304)
com.java.divers.EncodingFilter.doFilter(EncodingFilter.java:22)
j ai dans web.xml
index.jsp
20
PersistenceFilter
com.java.divers.EncodingFilter
PersistenceFilter
/*
est ce que peut m aidé pour résoudre ce probleme
merci d avance
Merci beaucoup pour l’astuce du filtre !
Ça a réglé un problème que je ne comprends toujours pas : le double encodage UTF-8, même si on met bien partout les
et
dans les JSP et un
request.setCharacterEncoding(« UTF-8 »); dans l’action…
Merci encore (si, si, j’insiste)
—
Stan
oups, tu filtres pas les balises, tu les enlèves carrément 🙂
je parlais des
<%@ page language= »java » pageEncoding= »UTF-8″ contentType= »text/html; charset=UTF-8″%>
et
<meta name= »Content-Type » content= »text/html; charset=UTF-8″ />
A ton service Stan ! 😉
Désolé pour les balises, mais c’est WordPress qui les enlève tout seul…
Merci bcp, ailleurs, rien n’est clair à ce sujet.
C’est avec plaisir Marco.
D’ailleurs, ce sujet est toujours d’actualité. je m’en suis encore servi sous Struts 2 récemment. 🙂
Bonjour,
merci pour votre post!
J’ai juste un complément d’information à apporter.
Pour que le filtre fonctionne correctement, il faut apparemment qu’il soit appliqué le plus tôt possible dans la chaîne des filtres. L’idéal est donc de placer le tag <filter-mapping> en première position du fichier web.xml, avant tous les autres tags <filter-mapping> eventuels.
Merci Benoît pour ce complément d’information. Je suis sûr que ça pourra aider des personnes. 😉
Merci beaucoup Seb… ça m’ a vraiment aidé
la 2 éme methode ca marche trés bien il faut juste ajouter mettre le filter au premier dans le web.xml
Un grand merci ! la seconde méthode fonctionne très bien sur Struts 2, mais il faut vraiment mettre le filter au premier dans le web.xml…
J’ai modifié l’article pour préciser que le filtre doit être déclaré en premier. Merci à tous pour m’avoir signalé ce détail. 😉
Bonjour j’ai appliqué cette méthode afin de succomber au problème d’encodage que j’ai eu auparavant . mais j’obtiens une erreur indiquant :
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
dans une autre ligne je trouve :
at EncodingFilter.doFilter(EncodingFilter.java:14)
comment faire ?
Merci pour le partage, j’ai adopté la méthode du filtre qui est extraordinaire.