7. Internationalisation

7.1. Notion de bundle

Nous avons déjà vu qu'un navigateur web pouvait être configuré avec une langue par défaut, et que cette langue est transmise au serveur dans les flux HTTP de requête. Nous avons également vu que cette langue était exposée dans les méthodes de la requête. On peut donc facilement imaginer un mécanisme, dans lequel une application web prendrait cette langue en compte pour afficher ses pages dans la bonne langue, celle du navigateur, automatiquement. Une application internationalisée est une application qui a la capacité de d'afficher ses pages dans différentes langues, et de choisir celle du navigateur, quand elle existe, automatiquement. Ce mécanisme repose entre autres, sur les ResourceBundle définis dans le JDK. Un ResourceBundle est un jeu de fichiers texte, qui suit une convention de nommage précise, et qui est rangé dans un même package. Le premier de ces fichiers texte porte le nom du bundle, par exemple : org.paumard.bundles.ApplicationBundle. Ce fichier doit alors porter le nom ApplicationBundle.properties, et être rangé dans le package org.paumard.bundles. Ce fichier est un fichier texte, qui contient des paires clés / valeurs, ligne par ligne.

Exemple 57. Fichier bundle racine

bonjour.le.monde=Bonjour le monde !
fermeture.application=L'application va se fermer

On peut compléter ce bundle avec d'autres fichiers, dans des langues différentes. Ces autres fichiers doivent suivre la convention de nommage suivante : on ajoute au nom le suffixe _fr, _en, etc... où les caractères qui suivent _ désignent le code de la langue de ce fichier. Dans notre exemple, le fichier ApplicationBundle_fr.properties aura même contenu que le fichier racine, et le contenu du fichier ApplicationBundle_en.properties sera en anglais.

Exemple 58. Fichier bundle en anglais

bonjour.le.monde=Hello world !
fermeture.application=The application will be shut down. 

On peut ainsi créer des fichiers en espagnol ( _es), en allemand ( _de), en italien ( _it), etc... À chaque fois, le fichier doit contenir les mêmes clés, et des valeurs dans la langue désignée. En Java, un bundle s'utilise de la façon suivante.

Exemple 59. Chargement d'un bundle

ResourceBundle bundle1 = 
   ResourceBundle.getBundle("org.paumard.bundles.ApplicationBundle") ;

ResourceBundle bundle2 = 
   ResourceBundle.getBundle("org.paumard.bundles.ApplicationBundle", 
                            Locale.ENGLISH) ;

System.out.println(bundle1.getString("bonjour.le.monde")) ;
System.out.println(bundle2.getString("bonjour.le.monde")) ;

On peut charger un bundle en passant à la méthode getBundle() la langue ( locale) dans laquelle on veut charger ce bundle. Si cette langue n'est pas définie, alors le bundle racine sera chargé. Notons que l'on peut lire la langue dans laquelle la JVM s'exécute en invoquant la méthode Locale.getDefault(). On imagine donc assez bien, à partir de cet exemple simple, comment l'internationalisation d'une application web va pouvoir fonctionner.

7.2. Internationalisation de pages JSP

L'internationalisation est gérée par les éléments de la librairie de tags standard fmt. Cette librairie est chargée de la façon suivante.

Exemple 60. Utilisation de la lirairie de tags fmt

<%@page contentType="text/html" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<!-- suite de la page -->

7.2.1. Positionnement de la langue dans une page

Le premier tag de cette librairie est le tag setLocale, qui permet de fixer la langue dans laquelle une page doit s'afficher. Ce tag ne doit être utilisé que si l'en-tête HTTP ne contient aucune indication de langue, ce qui ne devrait plus arriver sur les navigateurs récents. Il reste que ce tag peut être très utile en phase de mise au point.

Exemple 61. Tag setLocale

<fmt:setLocale value="fr_FR" scope="session"/>

Dans notre exemple, on positionne la langue à la valeur fr_FR (donc le français que l'on utilise en France), pour toute la session. L'attribut scope est l'attribut classique que l'on a déjà rencontré, et qui peut prendre les valeurs page, request, session et context.

7.2.2. Formater un message localisé

Examinons l'exemple suivant.

Exemple 62. Formatage des messages localisés

<%@page contentType="text/html" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">


<%@taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<fmt:setLocale value="en"/>

<jsp:useBean id="marin" beanName="marin" scope="session" 
             type="org.paumard.cours.model.Marin"/>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>

        <p>Locale = <%= request.getHeader("Accept-language") %></p>
        
        <fmt:bundle basename="org.paumard.cours.i18n.Messages">

            <p><fmt:message key="last-name"/> = <c:out value="${marin.nom}"/></p>
            <p><fmt:message key="first-name"/> = <c:out value="${marin.prenom}"/></p>

            <fmt:message key="greetings-name-first-name">
                <fmt:param value="${marin.nom}"/>
                <fmt:param value="${marin.prenom}"/>
            </fmt:message>
            <p></p>

        </fmt:bundle>


    </body>
</html>

Voici le contenu du bundle associé.

Exemple 63. Bundle associé

last-name=nom
first-name=prénom
greetings-name-first-name=Bonjour {0} {1}

Tout d'abord, remarquons que la déclaration d'un bundle suit la même syntaxe que dans une application Java classique : un bundle est désigné par son nom en tant que ressource. Remarquons ensuite que les éléments qui dépendent d'un bundle donné doivent être déclarés comme sous-éléments de l'élément bundle. La librairie de tags fmt nous donne un tag, message, qui permet de désigner une clé de ce bundle, et de l'afficher. Bien sûr, le message affiché est celui de la langue choisie par le système, ou explicitement. Les deux premiers messages de notre bundle sont des messages simples : first-name et last-name. En revanche, notre dernier message est en fait un format, qui déclare deux paramètres {0} et {1}. Fixer les paramètres de ce message, se fait ajoutant des sous-élément param à l'élément message.
Java servlet et JSP
Retour au blog Java le soir
Cours & Tutoriaux
Table des matières
Introduction
1. Position de l'API Servlet
2. Présentation
Présentation de Tomcat
1. Un peu d'histoire
2. Organisation des répertoires de Tomcat
2.1. Répertoire bin
2.2. Répertoire conf
2.3. Répertoire lib
2.4. Répertoire log
2.5. Répertoire temp
2.6. Répertoire webapp
2.7. Répertoire work
3. Lancement de Tomcat
3.1. Lancement par défaut
3.2. Accéder à l'administration de Tomcat
3.3. Plusieurs instances de Tomcat
4. Configuration de Tomcat
4.1. Introduction
4.2. Élément Server
4.3. Élément Service
4.4. Élément Connector
4.5. Élément Engine
4.6. Élément Host
4.7. Élément Context
4.8. Élément GlobalNamingResources
4.9. Élément Realm
4.10. Élément Valve
5. Définition et chargement des applications web
5.1. Introduction
5.2. Prise en compte des éléments Context
5.3. Chargement et mise à jour à chaud
6. Utilisation de Tomcat avec Apache
API Servlet
1. Introduction
2. Une première servlet
2.1. Le code
2.2. Création de l'application web
2.3. Déploiement dans Tomcat
3. Concepts, cycle de vie
3.1. Requête
3.2. Réponse
3.3. Session
3.4. Application web
3.5. Contexte d'exécution
3.6. Cycle de vie
3.7. Filtre
4. Présentation générale de l'API
4.1. Introduction
4.2. Interfaces disponibles
5. Notion de servlet
5.1. Interfaces servlet
5.2. Cycle de vie d'une servlet
5.3. Paramètres d'initialisation d'une servlet
6. Notion de requête
6.1. Accès aux paramètres d'une requête
6.2. Accès aux éléments de l'en-tête HTTP
6.3. Accès aux éléments de l'URL
6.4. Accès aux paramètres du client
6.5. Accès aux informations de sécurité
6.6. Accès à la session, au contexte et aux informations d'initialisation
7. Notion de réponse
7.1. Contrôle du buffer de sortie
7.2. Contrôle de la réponse HTTP
8. Notion de session HTTP
9. Redirection ou inclusion d'une ressource
10. Listeners
10.1. Introduction
10.2. Événements de l'API Servlet
10.3. Ajout ou retrait d'un attribut
10.4. Création et destruction d'un contexte
10.5. Notification d'un objet attaché à un contexte
10.6. Déclaration d'un listener dans une application web
11. Connexion à une base
11.1. Introduction
11.2. Connexion manuelle
11.3. Connexion par utilisation de source de données
Filtrage
1. Filtrage de servlets
2. Mise en place d'un filtre
2.1. Écriture d'un filtre
2.2. Déclaration du filtrage
3. Filtrage d'une requête
4. Filtrage d'une réponse
4.1. Fonctionnement de ce filtrage
Java Server Pages
1. Introduction
2. Un premier exemple
2.1. Une première JSP statique
2.2. Une première JSP dynamique
2.3. Fonctionnement interne des JSP
3. JSP scriplet
3.1. Les expressions
3.2. Les déclarations
3.3. Variables prédéfinies
3.4. Scriplet de directives
4. Utilisation de beans
4.1. Introduction
4.2. Déclaration d'un bean existant
4.3. Création d'un nouveau bean
4.4. Utilisation des propriétés d'un bean
5. Inclure un contenu externe dans une JSP
5.1. Introduction
5.2. Inclusion au lancement de l'application
5.3. Inclusion au traitement de la requête
6. Utilisation de bibliothèques de tags
6.1. Introduction
6.2. Bibliothèque core
7. Internationalisation
7.1. Notion de bundle
7.2. Internationalisation de pages JSP
Projet exemple
1. Présentation du projet