Système d'inclusion en JSF

Pour éviter les erreurs, voici un rapide rappel pour faire de l'inclusion de pages en JSF. Cet article contient un exemple de code classique, puis quelques points à ne pas oublier pour que tout se passe bien.

Le but de cet exemple sera d'avoir une page index.jsp qui inclue une page content.jsp.

index.jsp

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>JSP Page</title>
    </head>
    <body>
        <f:view>
            <f:subview id="content">
                <jsp:include page="content.jsp" flush="false" />
            </f:subview>
        </f:view>
    </body>
</html>

content.jsp

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<h:outputText value="Ceci est le contenu !" />

Points importants

Il existe quelques règles assez importantes pour que ce système d'inclusion de page marche correctement :
  • Dans la page de base, entourer l'inclusion avec une balise <f:subview />
  • Lors de l'inclusion, penser à mettre l'attribut flush à false. Cet attribut existe sur la plupart des balises permettant l'inclusion de pages.
  • Dans la page de destination, réutiliser les composants JSF directement, sans remettre de balise <f:view />
  • Les taglibs doivent quand à elles être réimportées.

Et voilà le résultat (en HTML) :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

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

    <body>
        Ceci est le contenu !
    </body>
</html>

Martin en parle également.

Permalink  |  Commentaires (0)

JSF + Tiles, complément

J'avais déjà parlé de coupler les avantages de JSF et Tiles, je reviens aujourd'hui rajouter un petit complément.

J'avais en effet parlé d'un inconvénient majeur, l'impossibilité de lier directement le rendu d'une page à une définition de Tiles.

J'ai découvert aujourd'hui, en lisant le tutoriel sur le site Tiles, que l'API de Tiles fournissait une Servlet qui liait les URL de type *.tiles vers les définitions correspondantes. Par exemple, grâce à cette Servlet, il est par exemple possible d'accéder à une définition nommée index via l'URL /index.tiles.

Après quelques tests, il est possible de coupler cette Servlet avec JSF.

Première étape : Déclarer la Servlet de Tiles

Dans web.xml :
<servlet>
    <servlet-name>Tiles Dispatch Servlet</servlet-name>
    <servlet-class>org.apache.tiles.web.util.TilesDispatchServlet</servlet-class>
</servlet>
...
<servlet-mapping>
    <servlet-name>Tiles Dispatch Servlet</servlet-name>
    <url-pattern>*.tiles</url-pattern>
</servlet-mapping>

Ainsi, toutes les URL *.tiles seront liées aux définitions correspondantes.

Deuxième étape : Configurer JSF pour utiliser les URL *.tiles

La seconde étape va consister à modifier légèrement le comportement de JSF. Par défaut, pour générer la réponse d'une requête index.jsf, le framework va chercher la page index.jsp. Nous allons maintenant lui dire d'aller chercher index.tiles à la place. Requête à laquelle Tiles répondra en introduisant une définition (la définition nommée index dans notre cas).

Il faut pour cela modifier une propriété propre à JSF :
<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.tiles</param-value>
</context-param>


Et voilà. Il ne reste plus qu'à essayer d'accéder à index.jsf. Le FacesContext est chargé, puis la main est passée à Tiles pour le rendu. Il suffit de déclarer nos JSP et nos définitions comme je l'ai précisé dans la première version.

Permalink  |  Commentaires (0)

JSF + Tiles

Combiner JSF et Tiles, c'est possible !

Voici comment j'ai réussi à mixer les deux :

1. Télécharger Tiles

La page de téléchargement est ici. J'ai utilisé la 2.0.5.

Une fois l'archive téléchargée et extraite, il faut récupérer les fichiers JAR de l'archive (situés à la racine et dans /lib, et les copier dans votre projet.

Ayant créé mon projet sous Glassfish, les librairies de JSF sont directement inclues dans le serveur d'application.

2. Configurer Tiles

La configuration de Tiles se passe en deux étapes. Une première étape consiste à déclarer une Servlet qui sera chargée au démarrage. La seconde étape consistera à déclarer un écouteur. Tout ça dans notre application Web.

Première chose, déclarer la Servlet de Tiles. Dans notre fichier web.xml :
<servlet>
    <servlet-name>TilesServet</servlet-name>
    <servlet-class>org.apache.tiles.web.startup.TilesServlet</servlet-class>
    <init-param>
        <param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
        <param-value>/WEB-INF/tiles-defs.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

Ensuite, l'écouteur (toujours dans web.xml) :
<listener>
    <listener-class>org.apache.tiles.web.startup.TilesListener</listener-class>
</listener>

3. Utiliser Tiles !

Dernière étape : tester l'installation !

On déclare une définition dans notre fichier /WEB-INF/tiles-defs.xml :
<definition name="test" template="/WEB-INF/pages/test.jsp">
</definition>

On crée ensuite le template correspondant à notre définition. S'agissant d'une simple page de test, j'ai fait plutôt simple :
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<h2><h:outputText value="Tiles works !" /></h2>

Il ne reste plus qu'à inclure nos définitions dans nos pages JSF :
<%@page contentType="text/html" pageEncoding="UTF-8" %>

<%@taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>

<f:view>
    <f:subview id="test">
        <tiles:insertDefinition name="test" flush="false" />
    </f:subview>
</f:view>

4. Inconvénients et astuces

Tiles est un framework très bien intégré à Struts. Il est possible, en utilisant Struts, de lier directement le rendu d'une action vers une définition Tiles.

Cela n'est malheureusement pas possible en JSF.

Une petite astuce permet cependant de passer à coté de cet inconvénient. Il s'agit de créer une JSP visible (en dehors de /WEB-INF) qui inclue directement la définition à utiliser. Au lieu de créer un lien vers une définition, il faudra alors créer un lien vers la JSP qui inclue cette définition.

Permalink  |  Commentaires (0)

Installer ICEfaces pour les nuls

C'est bien joli de faire des beaux billets de blog, mais t'aurais pu commencer par "Installer ICEfaces pour les nuls" :D
Martin

Et me voilà encore lancé dans un billet sur ICEfaces. Au programme aujourd'hui, l'installation de cette magnifique librairie.

Étape 1 : Création d'un projet Web sous NetBeans

On commence par créer un projet :
  • Nouveau projet
  • Projet Web
  • Web application
  • On lui donne on nom (ICEcalendar de mon coté)
  • Un emplacement (/home/viv/Desktop de mon coté [j'aime bien remplir mon bureau])
  • On lui donne un serveur d'application pour se déployer (GlassFish v2ur1 de mon coté)
  • On choisit les frameworks : JSF
  • Et on clique sur "Finish"

Étape 2 : Ajout des librairies

Pour commencer, il va falloir télécharger la librarie sur le site de ICEfaces (attention, inscription obligatoire).

Une fois l'archive ICEfaces-1.7.0-bin.zip téléchargée, nous allons récupérer les archives JAR de ICEfaces et les inclure dans notre projet. Nous allons donc extraire l'archive et copier tous les .jar situés dans /icefaces/lib vers notre projet NetBeans. Pour ce faire : Dans le projet, sur "Librairies" : Clic droit, "Add JAR/Folder...", et sélectionner tous les .jar à rajouter.

Étape 3 : Configuration de ICEfaces

Enfin, une fois les librairies ajoutées, passons à la configuration.

La seule véritable configuration à faire réside dans web.xml. Il faut configurer correctement les servlets de ICEfaces afin qu'elles puissent intercepter les requêtes des utilisateurs.

Personnellement, je pense que ce fichier de configuration est amplement suffisant pour travailler uniquement avec ICEfaces et JSF. À modifier en fonction des besoin de votre application (servlets personnalisées à rajouter le cas échéant, etc...).

Notes sur le fichier de configuration ci dessus :
  • La servlet de ICEfaces est configurée pour écouter les requêtes *.iface. L'URL pour accéder à /ma/page.jsp en utilisant ICEfaces sera donc /ma/page.iface.
  • La servlet de JSF est configurée pour écouter les requêtes *.jsf.

Étape 4 : Utilisation de ICEfaces

Quelques étapes à réaliser pour pouvoir utiliser ICEfaces dans vos pages JSP :
  • Pensez à importer la taglib dans chacune de vos JSP. L'URI complète de la taglib est http://www.icesoft.com/icefaces/component
  • Pensez aussi à importer les feuilles de style CSS de ICEfaces, grâce à la ligne <link href="./xmlhttp/css/rime/rime.css" rel="stylesheet" type="text/css" />. La feuille de style rime est ma préférée, mais d'autres sont disponibles.

Il est maintenant temps de tester notre installation de ICEfaces. Pour cela, quoi de mieux que d'essayer d'utiliser un calendrier ou de l'auto-complétion ?

En bonus, voici joint :

Permalink  |  Commentaires (1)

ICEfaces : Calendrier

stoi la face de glaçon

Sur cette magnifique citation, je me suis remis à ICEfaces. Au programme aujourd'hui : le calendrier.

Calendrier


J'ai choisi le calendrier pensant m'attaquer à un composant un peu plus difficile que l'auto-complétion. C'était mal connaître ICEfaces. Une fois de plus, la facilité à été au rendez-vous.

Première étape : la création d'un JavaBean. Rien de bien compliqué, juste deux champs, et les getters / setters associés. Et c'est tout.
package com.aperigeek.icefaces.calendar;

import java.util.Date;
import java.util.TimeZone;

public class CalendarBean {

    private Date date = new Date();
    
    private TimeZone timeZone = TimeZone.getDefault();

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public TimeZone getTimeZone() {
        return timeZone;
    }

    public void setTimeZone(TimeZone timeZone) {
        this.timeZone = timeZone;
    }

}

Une petite déclaration dans faces-config.xml :
<managed-bean>
    <managed-bean-name>calendarBean</managed-bean-name>
    <managed-bean-class>com.aperigeek.icefaces.calendar.CalendarBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

Et il n'y a plus qu'à l'utiliser :
<ice:selectInputDate id="calendar" value="#{calendarBean.date}">
    <f:convertDateTime timeZone="#{calendarBean.timeZone}" />
</ice:selectInputDate>

La seule difficulté dans ce code réside dans la balise <f:convertDateTime />. Il est très important de spécifier un attribut timeZone, sans lequel votre composant <ice:selectInputDate /> lèvera une NullPointerException !

Après investigation, il semblerais que l'attribut timeZone soit obligatoire si et seulement si vous insérez une balise f:convertDateTime dans votre calendrier. Le code suivant est conc suffisant :
<ice:selectInputDate id="calendar" value="#{calendarBean.date}" />

Permalink  |  Commentaires (2)