Category: Java J2EE

Fiji 2.0 : Intégration de Flex avec JSF

By , 17/09/2010

Le framework fiji de Exadel a fait l’actualité en septembre 2008 car il permettait d’intégrer des composants Flex au framework Java JSF. La vitrine de composant graphique basée sur Amchart était très bien faite. C’est sur ce point que je trouvais Fiji prometteur. Après l’avoir essayé, j’étais assez déçu car fiji n’est pas déployé sur les repositories Maven, la release publiée se base sur des versions SNAPSHOT, elle dépend de Richfaces, etc. De plus depuis fin 2008, j’ai eu l’impression que le projet était abandonné car il n’y eu jamais d’autre release.

Par hasard, je suis tombé sur cet article du blog de Max Katz, il y a quelques jours. On peut y apprendre qu’il travaille sur une version 2.0 open source du fameux framework. A priori la publication de la version est proche. J’espère rédiger un petit tutoriel basé sur une application J2EE6 intégrant des graphiques Amchart lors de la publication.

Comment utiliser le timezone du compensant JSF convertDateTime

By , 10/09/2010

Par défaut, JSF utilise le timezone GMT dans le composant convertDateTime. C’est problématique lorsqu’un développeur veut afficher des dates qui ne sont pas formatées en GMT. Pour une application en France cela occasionne un décalage d’un jour dans le passé. En recherchant une solution sur google j’ai trouvée des personnes qui créent leur propre convertisseur. En fait, il est en fait plus facile d’utiliser l’attribut timezone du composent.

L’attribue timezone attend directement une chaine de caractère et non un objet de type java.util.TimeZone comme je le pensais au début. Par exemple, voici comment mettre le timezone sur Paris :


<h:outputText value="#{commande.date}">
   <f:convertDateTime pattern="dd/MM/yyyy" timeZone="Europe/Paris" />
 </h:outputText>

Problème d’export Excel avec le Datatable exporter de Seam

By , 09/09/2010

Seam permet d’exporter très simplement des dataTable JSF en CSV ou en Excel. Pour cela il suffit de déclarer une dataTable et un lien qui fait référence au bon composant Seam :


<h:form id="theForm">
      <h:dataTable id="theDataTable" value="#{personList.personList}"
            var="person">
                  ...
      </h:dataTable>
</h:form>

...

<h:commandLink
      value="Export"
      action="#{excelExporter.export('theForm:theDataTable')}"
      />

Cette fonctionnalité est très pratique mais lorsqu’il y a un problème il est parfois très compliqué de trouver l’erreur. J’ai ainsi découvert par hasard que les colonnes doivent être composées de composants JSF et non de chaines de caractères simples pour apparaître dans l’export. Dans l’exemple suivant, seule la première colonne apparaîtra dans l’export :


<h:form id="theForm">
      <rich:dataTable id="theDataTable" value="#{personList.personList}"
                  var="person">
            <rich:column>
                  <f:facet name="header"><h:outputText value="Name"/></f:facet>
                  <h:outputText value="#{person.name}" />
            </rich:column>
            <rich:column>
                  <f:facet name="header"><h:outputText value="Age"/></f:facet>
                  #{person.age}
            </rich:column>
      </rich:dataTable>
</h:form>

Pour information, ce comportement est aussi valable pour le facet header. Ce comportement est enregistré en tant que “nouvelle fonctionnalité” dans le JIRA de Seam : https://jira.jboss.org/browse/JBSEAM-3213

Utiliser les fonctions JSTL avec l’EL de JSF

By , 09/09/2010

La JSTL est très utile dans le développements des pages JSP et JSF. Elle permet d’avoir à disposition une multitude de fonctionnalités sans avoir à repasser par une classe Java (opérations sur les dates, les chaines de caractères, etc.) voici un lien vers la javadoc : http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/index.html. Pour utiliser ces fonctions dans une page JSF avec du JSP :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page contentType="text/html" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
     <h:outputText value="${fn:toLowerCase('CALIFORNIA')}"/>
</html>

Pour utiliser ces mêmes fonctions dans une page avec Facelets :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:z="http://www.qualcomm.com/jsf/core"
      xmlns:c="http://java.sun.com/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions">
          <h:outputText value="#{fn:toLowerCase('CALIFORNIA')}"/>
</html>

weblets

By , 02/07/2010

En travaillant sur une librairie JSF faite maison, j’ai rapidement souhaité packager des fichiers CSS et des images. Avec richFaces, il est possible de charger un fichier CSS se situant dans un JAR avec le composant <a4j:loadStyle />, mais je n’ai pas trouvé la même fonctionnalité pour récupérer une image packagée dans un JAR. C’est alors que j’ai découvert weblets :

Component libraries for web application frameworks often need to provide resource files along with implementation classes. For example, JavaServer Faces Renderers often need JavaScript, CSS and image resources.

Il s’agit donc d’un framework qui met à la disposition d’une application web les ressources contenues dans un JAR “tag-librairie”. Cette technologie est compatible avec JSF, JSP, JavaScript, CSS, etc. Elle est utilisable dans une application basée sur JSF ou sur des servlets.

La librairie

Il n’y a qu’une seule règle à suivre pour le packaging de la librairie : le fichier de configuration weblets-config.xml doit être dans le répertoire META-INF. Voici un exemple de fichier de configuration :

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
      <description>Weblets Demo</description>

      <servlet>
        <servlet-name>Weblets Servlet</servlet-name>
        <servlet-class>net.java.dev.weblets.WebletsServlet</servlet-class>
      </servlet>

      <!-- The  Weblets servlet mapping must be path based otherwise  Weblets will fail! -->
      <servlet-mapping>
        <servlet-name>Weblets Servlet</servlet-name>
        <url-pattern>/weblets/*</url-pattern>
      </servlet-mapping>

    </web-app>

Ce fichier ressemble étrangement au fichier web.xml. Ici, toutes les ressources qui sont dans le package org.myapp.faces.renderer.html.resources seront disponibles à l’adresse http://…../root-webapp-context/faces/weblets/myressources/*. Le nom de la weblet est myweblet. Il peut y avoir plusieurs weblets dans un même fichier de configuration.

Je n’aime pas la paraphrase, vous trouverez toutes les explications utiles à cette adresse : https://weblets.dev.java.net/doc_11/longdoc/packingweblets.html

Mise en place sur une application web JSF

Dans une application JSF, la weblets se déploie automatiquement. Il n’y a que deux limitations :

  • Utiliser la servlet JSF de l’implémentation de référence :  javax.faces.webapp.FacesServlet
  • Utiliser le mapping de servlet JSF /faces/*

Voici un exemple de fichier web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <description>Weblets Demo</description>

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>

</web-app>

Si vous utiliser Seam comme moi, votre mapping de servlet est certainement *.seam. Il faut s’avoir qu’il est possible de définir plusieurs mappings différents sans aucun problème. Pour plus d’explication je vous invite à visiter la documentation officielle : https://weblets.dev.java.net/doc_11/longdoc/setup.html

Utilisation dans l’application JSF

L’utilisation dans votre application JSF est très simple. Dans une page facelets :

#{weblet.url['weblets.demo']['/welcome.js']} <!– avec weblets.demo = le nom de la weblet et /welcome.js le chemin de la resource –>

Dans un fichier CSS :

background-image: url( weblet:resource( "weblets.demo" , "/myimage.png" ) );

Maven

Enfin, comme toute librairie qui se respecte, voici comment l’utiliser avec maven : Ajouter le repository java.net à votre pom.xml :

<repository>
 <id>maven2-repository.dev.java.net</id>
 <name>Java.net Repository for Maven</name>
 <url>http://download.java.net/maven/2/</url>
 <layout>default</layout>
 </repository>
<pre>

Ajouter les deux dépendances suivantes :

<dependency>
 <groupId>net.java.dev.weblets</groupId>
 <artifactId>weblets-api</artifactId>
 <version>1.1</version>
 </dependency>
 <dependency>
 <groupId>net.java.dev.weblets</groupId>
 <artifactId>weblets-impl</artifactId>
 <version>1.1</version>
 </dependency>

Pour terminer cet article, j’ajouterai que j’ai eu beaucoup de difficultés pour mettre en place ma librairie car la documentation n’est pas tout à fait correcte ou plutôt, elle induit en erreur le développeur de temps en temps. Il ne faut pas avoir peur de checkouter les sources pour s’inspirer des exemples, la racine du repository subversion est : https://weblets.dev.java.net/svn/weblets avec l’utilisateur guest sans mot de passe. Cela vous fera certainement gagner du temps.

org.myapp.faces.renderer.html.resources

Facelets et JSTL

By , 06/06/2010

Il est important de savoir que l’utilisation de Facelets est compatible avec l’utilisation de certaines fonctionnalités de la JSTL.

En lisant la documentation de Facelets, j’ai découvert que seulement cinq fonctions sont implémentées :

  • c:if
  • c:forEach
  • c:catch
  • c:set

J’ai aussi remarqué que leurs utilisations n’est pas toujours possible. Par exemple, il n’est pas possible de demander un c:if dans un ui:repeat. Dans ce cas, j’ai du remplacé le ui:repeat par un c:forEach pour que mon instruction conditionnelle soit prise en compte.

Ecrire un document XML avec Facelets

By , 05/06/2010

Générer un document XML à partir d’un application web Java est très simple. Il suffit d’écrire une servlet qui va écrire du XML sur la réponse HTTPResponse avec le bon type de contenu. Voici un exemple :

try {
 FacesContext ctx = FacesContext.getCurrentInstance();
 final HttpServletResponse resp = (HttpServletResponse)ctx.getExternalContext().getResponse();
 String xml = "<settings>...</settings>";
 resp.setContentType("text/xml");
 resp.setContentLength(xml.length());
 resp.getOutputStream().write(xml.getBytes());
 resp.getOutputStream().flush();
 resp.getOutputStream().close();
 ctx.responseComplete();

} catch (IOException e) {
 e.printStackTrace();
}

L’opération s’avère plus difficile lorsqu’il faut l’écrire à partir d’une page XHTML en utilisant Facelets. Voici une solution possible :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" contentType="text/xml">

<settings>...</settings>

</f:view>

La déclaration de la dtd HTML (deuxième et troisième lignes) n'est pas nécessaire sauf si vous utilisez des caractères latins ("é", "è", etc.) car facelets les traduit automatiquement en caractères HTML du style "&eacute;" et cela provoque l'erreur "Erreur d'analyse XML : entité non définie" sans ce fichier dtd.

OfficeFolders theme by Themocracy