Encodage UTF-8 dans JCMS

1. Introduction

Depuis la version 5.5 de JCMS, toutes les ressources et flux sortant/entrant de JCMS sont encodés en UTF-8 qui est un format de codage de caractères Unicode (UCS).

Ceci concerne les ressources suivantes :

  • Fichiers
    • WEB-INF/data/store.xml
    • WEB-INF/data/workflow.xml
    • Propriétés (WEB-INF/*/*.prop)
    • JSP (*.jsp)
    • Sources java (WEB-INF/classes/*.java)
  • Flux
    • Requêtes HTTP (display.jsp, *.jsp, servlet JSync)
    • E-mails
    • Statistiques et fichiers de log (WEB-INF/data/stats/* et WEB-INF/data/logs/*)
    • Export RSS/Atom
    • Export XML (displayXml.jsp, queryXml.jsp et statusXml.jsp)
    • Export CSV (par défaut en ISO-8859-1, modifiable avec la propriété csv.charset)
    • WebDAV (par défaut en ISO-8859-1, modifiable avec la propriété channel.webdav.encoding)

2. Recommandations de développement

2.1 Sources Java

Les règles suivantes doivent être respectées pour garantir l'usage du bon encodage, indépendamment de la configuration de la plate-forme sur laquelle est hébergée JCMS (OS, JVM et serveur d'application).

2.1.1 Servlet et ServletFilter

Dans les Servlets précisez request.setCharacterEncoding("UTF-8") avant tout appel à request.getParameter(String) pour assurer le bon décodage des paramêtres par le serveur d'applications. Pour les ServletFilter, ca n'est pas nécessaire si elles se situent après la InitFilter de JCMS 5.5 qui s'en charge. Dans le cas contraire, il faut faire la même déclaration pour les Servlets.

2.1.2 String.getBytes()

Utilisez systématiquement la méthode String.getBytes(String) ou l'on précise l'encodage :

String.getBytes() ==> String.getBytes("UTF-8")

2.1.3 RandomAccessFile.write...

N'utilisez pas RandomAccessFile.writeUTF() qui ajoute un BOM (Byte Order Mark), ni tout autre méthode "write" de la classe RandomAccessFile à l'exception de RandomAccessFile.write(byte ), en ayant au préalable converti votre String en bytes UTF-8.

raf.write(strToWrite.getBytes("UTF-8"))

2.1.4 ByteArrayOutputStream

Pensez à correctement convertir les ByteArrayOutputStream en UTF-8, par exemple:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
...
String str = baos.toString("UTF-8");
2.1.5 FileReader et FileWriter

N'utilisez plus FileReader(String|File) et FileWriter(String|File), qui utilise l'encodage par défaut de la plate-forme, mais à la place :

// FileWriter
Writer w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

// FileReader

Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));

Cependant, pensez à bien conserver le paramètre append dans FileInputStream le cas échéant.

2.1.6 PrintStream

Utilisez pas le constructeur PrintStream(...) en précisant l'encodage :

new PrintStream(fos, false, "UTF-8");

2.2 Sources JSP

2.2.1 Encodage des JSP

Ajoutez systématiquement la directive contentType au début des JSP qui contiennent des caractères non ASCII:

<%@ page contentType="text/plain; charset=UTF-8"%>

Cet ajout est réalisé automatiquement par l'utilitaire de conversion UTF8Converter (à partir de JCMS 5.6) lorsque vous migrer une webapp antérieur à JCMS 5.5.

2.2.2 Content-Type des JSP

Lorsque vous avez besoin de modifier le content-type de sortie d'un JSP (pour faire du XML ou du CSV par exemple), précisez l'attribut de requête ContentType avant l'inclusion de doInitPage.jsp (attribut spécifique à JCMS).

<%
  // inform doInitPage to set the proper content type
  request.setAttribute("ContentType", "text/xml; charset=UTF-8"); 
%><?xml version="1.0" encoding="UTF-8"?>
<%@ include file="/jcore/doInitPage.jsp" %>

2.3 Fichiers statiques

2.3.1 HTML

Précisez l'entête suivante le plus tôt possible dans la balise head :

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

2.3.2 XML

Ajoutez l'entête XML UTF-8 en tout début de fichier :

<?xml version="1.0" encoding="UTF-8"?>

3. Migration d'une ancienne webapp 

3.1 Configuration du serveur d'applications

Consultez le manuel d'installation et d'exploitation pour configurer votre serveur d'application correctement pour JCMS.

Par exemple, pour Tomcat, vous devez impérativement ajoutez la directive URIEncoding='UTF-8' dans tous les connecteurs que vous utilisez dans votre installation (conf/server.xml). Ceci est valable pour les connecteur HTTP (Coyote) comme pour les connecteurs AJP.
Notez que cette modification est incompatible avec les anciennes versions de JCMS. Si d'autre webapps JCMS 5.0 ou 4 fonctionnent avec ce connecteur, déclarer un nouveau connecteur pour la migration.

3.2 Conversion des fichiers

Voici la démarche à suivre si vous devez migrer une ancienne webapp antérieure à JCMS 5.5 :

Après avoir récupéré un delta de votre webapp via le Gestionnaire des changements, utilisez l'utilitaire UTF8Converter pour convertir automatiquement l'ensemble des fichiers qui ne sont pas déjà en UTF-8 :

  • Dans la nouvelle version de JCMS, aller sur admin/classpath.jsp et suivre les instructions. Garder la fenêtre de commande ouverte, vous en aurez besoins à l'étape 3 pour la conversion UTF-8.
  • Dans la fenêtre de commande, déplacez vous dans le répertoire parent du répertoire delta.
  • Lancer le UTF8Converter sur le répertoire delta :
    • java com.jalios.jcms.tools.UTF8Converter delta

Outre la conversion UTF-8, le convertisseur fournit dans JCMS se charge de modifier les entêtes des fichiers XML et d'ajouter la directive contentType pour les JSP (uniquement à partir de JCMS 5.6).

En résumé...

Cet article décrit les règles de développement à respecter dans JCMS pour assurer le bon encodage en UTF-8 des fichiers et des flux entrant/sortant.

Sujet
Produits
Publié

30/06/06

Rédacteur
  • Olivier Jaquemet