RSS Feed

Les bonnes pratiques avec Struts – afficher les formulaires en UTF-8

31 August 2006 par SeB 14 commentaires »

Voici 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[1].

Solutions

Il existe deux solutions courantes pour répondre à ce problème, qui s’implémentent :

  • dans les méthodes reset() et validate() de la classe ActionForm
  • 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 base BaseActionForm.
  • 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. :-D

Notes

[1] Comme les caractères accentués tels que é, è, à, ô, …

 

14 réactions sur “Les bonnes pratiques avec Struts – afficher les formulaires en UTF-8”

  1. davy says:

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

  2. SeB says:

    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…

  3. mami rejeb says:

    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

  4. Stan says:

    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

  5. Stan says:

    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″ />

  6. SeB says:

    A ton service Stan ! ;-)

    Désolé pour les balises, mais c’est WordPress qui les enlève tout seul…

  7. marco says:

    Merci bcp, ailleurs, rien n’est clair à ce sujet.

  8. SeB says:

    C’est avec plaisir Marco.
    D’ailleurs, ce sujet est toujours d’actualité. je m’en suis encore servi sous Struts 2 récemment. :-)

  9. Benoît says:

    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.

  10. SeB says:

    Merci Benoît pour ce complément d’information. Je suis sûr que ça pourra aider des personnes. ;-)

  11. Diddy says:

    Merci beaucoup Seb… ça m’ a vraiment aidé

  12. jalil says:

    la 2 éme methode ca marche trés bien il faut juste ajouter mettre le filter au premier dans le web.xml

  13. Pierre says:

    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…

  14. SeB says:

    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. ;-)

Réagissez