jsp:include et l'encodage
Par Benjamin le samedi 9 août 2008, 12:13 - technique - Lien permanent
Il est rare de ne pas rencontrer de problème d'encodage quand on développe une application web en Java. Voici un petit pense-bête pour résoudre une difficulté associée à l'utilisation d'inclusions dynamiques (<jsp:include />) dans les JSP.
Imaginons que vous ayez à développer des pages avec un encoding UTF-8. Vous prendrez bien sûr soin d'inclure dans toutes vos JSP des entêtes de la forme :
<%@page language="java" contentType="text/html; charset=UTF-8"%>
Cette routine permet de préciser d'un seul coup au container que la requête, la réponse et la JSP sont encodées en UTF-8 (au passage, vérifiez que votre éditeur de JSP sauvegarde bien vos JSP en UTF-8)
Cela fonctionne bien pour des JSP simples, mais dès que l'on s'amuse à inclure des JSP les unes dans les autres avec des <jsp:include>, patatra... Les belles pages vont se mettre à afficher des caractères bizarroïdes à la place des caractères accentués...
D'où vient ce mystérieux problème qui traduit à l'évidence un problème d'encodage alors que vous avez soigneusement tout précisé ?
On vérifie qu'il s'agit bien d'un problème d'encodage en ajoutant sur les pages incluses des traces du genre :
<%= response.getCharacterEncoding()%>
qui, ô surprise, afficheront ISO-8859-1, ce qui signifie que le container n'a pas tenu compte de votre indication d'encodage.
En fait, l'encodage par défaut utilisé par la JVM est ISO-8859-1. On aura beau préciser en lancement de la JVM un -Dencoding.file=UTF-8, rien n'y fera : la JVM se souviendra que son encodage par défaut est ISO-8859-1. Et en fait, lorsque l'on fait un <jsp:include> sur une JSP, le container va généralement choisir l'encodage par défaut de la JVM, donc ISO-8859-1. Généralement, mais pas toujours! Il existe heureusement une exception : si l'encodage de la réponse a au préalable été affecté, il restera inchangé. Donc, si avant que le container n'ait récupérer un Writer sur l'HTTPServletResponse, vous avez fait un setCharacterEncoding("UTF-8"); sur l'HTTPServletResponse, l'encodage sera correct.
D'où une solution de contournement de ce problème : elle consiste à ajouter un filtre (Filter) en interception de toutes les requêtes pour aller positionner correctement l'encodage de la réponse avant que le container ne fasse des bêtises...
Il faut donc déclarer un filtre dans le web.xml :
<filter>
<filter-name>encodage</filter-name>
<filter-class>fr.publo.EncodageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encodage</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
lequel filtre se réduira à :
package fr.publo;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class EncodageFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
public void init(FilterConfig arg0) t
throws ServletException {
}
}
Si cet article vous a intéressé, n'hésitez pas à nous laisser un commentaire ou à vous abonner à notre flux RSS.
Peut-être serez-vous également intéressé par ces articles :
Commentaires
Article très pertinent, j'ajouterais juste que la méthode response.setCharacterEncoding("") n'est disponible qu'à partir de l'implémentation "Servlet 2.4".... snif
Bonne remarque à propos de
ServletResponse.setCharacterEncoding(String)qui n'apparaît qu'avec les Servlets 2.4. Pour ceux qui utilisent les implémentations antérieures à 2.4, il reste la méthodeServletResponse.setContentType(String)qui permet entre autres de préciser l'encoding.Par exemple :
response.setContentType("text/html;charset=UTF-8")une autre maniere de voir les choses!! :)