Archive for février, 2007

Problème d’accents dans les applications web

La gestion des accents dans les applications web n’est toujours pas, quelque chose de simple qui marche sans qu’on s’en préoccupe !

Quand le navigateur soumet un formulaire, il poste les valeurs des champs en utilisant le même encodage que celui de la page html d’origine.
Dans une jsp, pour spécifier au moteur de servlet l’encodage du flux de la réponse http et donc de la page html générée, nous avons recours à la directive @page comme ceci :

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

Renseigner l’attribut contentType a deux effets ; premièrement d’encoder la réponse dans le format choisi, deuxièmement de l’indiquer au client, par le biais d’une variable dans l’entête http.
Il est cependant intéressant de mentionner cet encodage directement dans la page html. Ainsi, elle pourrait être parsée à nouveau correctement ; par exemple ré-affichée après avoir été sauvegardée sur le disque. Il est donc plus prudent d’ajouter la balise suivante entre les tags head :

<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>

Enfin, nous pouvons remarquer que la directive @page support également un attribut « pageEncoding ». Cet attribut précise simplement l’encodage de la page jsp elle même. Cette information sert au moment de la compilation de la jsp pour produire la servlet correspondante. Cette valeur dépend de l’IDE, NetBeans (dans sa configuration initiale) sauvegarde les fichiers en utilisant l’encodage par défaut de l’OS : CP-1252 pour Windows et UTF-8 pour linux.

Côté serveur, il faut décoder les paramètres de la requête http avec le même encodage que celui qui a servi à la transmission du formulaire.
Mais quel est celui utilisé quand on appelle HttpServletRequest.getParameter(name) ?
En théorie, à l’instar de ce que fait le serveur dans sa réponse, le navigateur est censé communiquer au serveur, dans l’entête http, l’encodage employé.
Malheureusement, dans la pratique ni Internet Explorer ni Firefox ne le fait. Pour s’en convaincre il suffit d’appeller HttpServletRequest.getCharacterEncoding() et constater que la méthode retourne null.
La conséquence de cela est que si l’object HttpServletRequest ne connait pas l’encodage dont s’est servi le client, il en utilisera un par défaut. Ce paramétrage est propre au serveur d’application, Glassfish par exemple, utilise l’ISO-8859-1. Il est évidemment possible de le changer.
Il est aussi possible de modifier le « CharacterEncoding » programmatiquement grâce à la méthode setCharacterEncoding(value). Si l’application est développée à l’aide d’un framework web (JSF, struts…), il faudra définir un HttpServletFilter pour le faire avant que les couches du framework n’accèdent à la requête.