ILife 09, premières impressions
Après des années de bon & loyaux services sous windows. Après avoir monté mes propres machines pour essayer d’optimiser un tant soit peu ma machine, et ainsi avoir des performances décentes sur mon ordinateur personnel, j’ai cherché un alternative, qui me permettrait d’utiliser mon ordinateur pour produire du contenu (code, articles, media...). Je travaille actuellement dans un service de geek, et une bonne partie d’entre eux, n tarit pas d’éloge sus macintosh. J’ai donc fait un POC Imac, qui a réussi avec succès. Depuis novembre, j’ai également craqué en achetant un macbook pro unibody. Je suis maintenant un utilisateur assidu d’iphoto et d’iMovie (ma chère et tendre monte d’ailleurs elle-même les vidéos familliales. Cet article est là pour vous sentiments après l’arrivée toute fraiche de cette nouvelle version. Mes remarques seront cependant limitées à imovie et iphoto, car ce sont les seuls produits de la gamme ilife que j’utilise.
Java, valider votre code html avec jtidy
Pour les adeptes de cet addon assez connu des développeurs web soucieux de leur conformité html, il existe également une version java de cet outil. Ce petit exemple de code montre comment parser la home de ce site, et également d’en afficher le rapport.
Introduction au Framework MVC Spring
Le design pattern MVC est un modèle de conception adapté à la séparation des couches.
Cette méthode impose de séparer présentation, traitements et données.
En respectant cette méthodologie, le travail en équipe sera facilité par le découpage des tâches et des fichiers. La maintenance du code sera améliorée du fait de sa spécialisation. Bref, que des avantages.
Le Framework Spring implémente ce design pattern.
Dans cet article qui lui est consacré, nous allons mettre en pratique cette séparation des couches en utilisant un MultiActionController, qui me semble plus simple pour commencer.
Réécriture des URL / URL Rewriting en java

L’URL rewriting est aujourd’hui le garant d’un meileur référencement pour les sites web dynamiques.
En effet, les moteurs de recherche n’indexent pas ou moins bien les url dotées d’un grand nombre de paramètres.
Les url telles que http://www.monsite.com/index.php ?param1=1234¶m2=abcd ne sont pas très parlantes alors que www.monsite.com/rewriting-ur... est humainement lisible et davantage mémorisable.
Et pour finir, le fait de pouvoir placer des mots clés dans l’url sera bien sûr bénéfique au référencement de celle-ci.
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
</filter-class>
</filter>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
<!-- pattern des url qui vont etre reecrites -->
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Toutes les url demandées seront filtrées car nous avons utilisé le pattern /* mais nous pourrions aussi utiliser d’autres patterns tels que *.htm, *.html…
Maintenant nous allons écrire notre première règle :
<urlrewrite> <rule enabled="true"> <from>^/([0-9]+)\-([0-9]+)\-([a-z0-9\-\.]+)\.htm$</from> <to>index.jsp ?param1=$1&param2=$2</to> </rule> </urlrewrite>
Cette règle transforme une url du type http://www.monsite.com/1234-9876-url-rewriting.htm en une url du type www.monsite.com/index.jsp?param1=1234¶m2=9876 qui sera utilisable par la webapp.
Il est bien sûr possible de multiplier les règles selon les besoins de l’application.
Voilà, notre filtre est prêt, nous pouvons désormais utiliser des url du type :
http://www.cestpasdur.com:8080/demo_rewriting/1-2-url-rewriting.htm
http://www.cestpasdur.com:8080/demo_rewriting/12345-098765-url-rewriting-tuckey.htm
Il existe d’autres solutions qui permettent la réécriture des url, par exemple, apache est doté d’un mod_rewrite qui fonctionnant de concert avec un .htaccess permettra d’effectuer les mêmes manipulations d’URL, certainement de manière plus performante, mais peut être, un peu moins dynamique.
Webapp avec maven et JSF
Pourquoi JSF ?
Si je n’avais droit qu’à une phrase pour répondre à cette question, je dirais “Simplifier le développement rapide d’interface riche, tout en facilitant la maintenance”. Et maintenant que je ne suis plus limité à une seule phrase, je dirais :
Système de templating évolué (myFaces),
Rendre une application web riche (R.I.A.) avec RichFaces,
Développement rapide grâce aux composants html fournis (liste extensible)
Application M.V.C
Bien d’autres encore…
Mise en place de la servlet JSF
web.xml
… <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>*.htm</url-pattern> </servlet-mapping>
Dans la plupart des exemples, on peut voir des patterns d’urls du types *.faces, je ne vois pas vraiment l’intérêt de faire connaître à nos visiteurs le type de technologie utilisées. Question sécurité de l’application, mieux vaut en dire le moins possibles, donc, j’ai utilisés *.htm (même si ce n’est pas du contenu statique).
Les dépendances suivantes sont à ajouter dans pom de la webapp (nécessaires pour le bon fonctionnement de la servlet
Pom.xml (webapp)
… <dependency> <groupId>javax.faces</groupId> <artifactId>jsf-impl</artifactId> <version>1.2_08</version> </dependency> <dependency> <groupId>javax.faces</groupId> <artifactId>jsf-api</artifactId> <version>1.2_08</version> </dependency> …
Première page JSF helloWorld (index.jsp)
<%@ taglib uri=”http://java.sun.com/jsf/html” prefix=”h” %> <%@ taglib uri=”http://java.sun.com/jsf/core” prefix=”f” %> <html> <head> <title>Hello World</title> </head> <body> <f:view> <h1>Hello world</h1> </f:view> </body> </html>
Mettre en place une redirection pour la première page
Lorsque l’on tape dans son navigateur http://localhost:8080/seriestv-war/, et si notre première page JSF s’appelle index.jsp, le serveur essaye de nous afficher directement la page index.jsp, ce qui nous envoie au final l’exception java.lang.RuntimeException : Cannot find FacesContext. En gros, il nous manque le contexte JSF, un peu normal, nous ne sommes pas passé par la servlet (pour rappel le filtre est *.htm), mettre le filtre à *.jsp ne fonctionne pas non plus. Nous allons donc ajouter deux choses pour que cela fonctionne :
web.xml
… <welcome-file-list> <welcome-file>default.jsp</welcome-file> </welcome-file-list> …
et le code de notre page default.jsp
<jsp:forward page=”index.htm”/>
Afficher la valeur d’un managed bean dans une page JSF
Afin de pouvoir afficher les valeurs des propriétés d’un managed bean dans une page JSF il faut auparavant déclarer celui-ci dans le fichier de configuration JSF (faces-config.xml)
… <managed-bean> <managed-bean-name>serieBean</managed-bean-name> <managed-bean-class>com.cestpasdur.seriestv.managedbeans.SerieBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> …
Ensuite ce managed bean doit être un pojo, donc ces propriétés doivent être accessibles via … des accesseurs.
Vous pouvez ajouter une propriété bidon ainsi que ses accesseurs dans notre managed bean afin de vérifier que notre application JSF fonctionne correctement.
…
private String test="damien";
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
…
}
Maintenant que tout est prêt, nous devons maintenant afficher cette propriétés dans notre page JSF :
<h:outputText value="#{serieBean.test}"/>
Pas besoin de redémarrer le serveur, normalement jetty a pris en compte à chaud vos modifications, actualisez la page, ca marche.
C’est ok, sur jetty, mais nous voudrions voir si c’est portable sur un serveur d’application plus usité en production comme jboss
Au démarrage du serveur, nous obtenons l’exception suivante :
java.lang.ClassCastException : com.sun.faces.config.WebConfiguration
Boss inclut déjà dans son classPath sa propre implémentation de JSF, mais jetty lui en a besoin pour fonctionner. Afin que les deux cas fonctionnent, nous allons ajouter un profil, qui nous permettra selon son activation ou non, de faire certaines adaptations. Pour jboss, nous devons juste surcharger le scope qui est a compile par defaut avec les lignes suivantes dans le pom du war :
<profiles>
<!–- profil permettant de surcharger les scopes lors de la création du war pour jboss -–>
<profile>
<id>jboss</id>
<dependencies>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>1.2_08</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>1.2_08</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>
Afin de l’utiliser, nous allons utiliser la commande suivante :
mvn clean install -Pjboss
Le war passe de 1 Mo à 8 ko, je pense que c’est bon. Si on teste sur jboss, désormais, çà fonctionne…
A ce point je vous encourage à continuer et ajouter une dataTable dans votre page JSF ainsi que les données correspondantes dans le managed bean.
Ajouter le support de richFaces
Ajouter le repository suivant dans le pom parent du projet :
<!–- Needed for RichFaces -–> <repository> <id>jboss.org</id> <url>http://repository.jboss.org/maven2/</url> </repository>
Afin de récupérer les dépendances dont nous avons besoin, nous devons ajouter dans le pom du war :
<!-- dependances richfaces --> <dependency> <groupId>org.richfaces.ui</groupId> <artifactId>richfaces-ui</artifactId> <version>3.2.0.GA</version> </dependency>
Afin de nettoyer le classPath et télécharger les dépendances nécessaires :
mvn clean eclipse:eclipse
… <!-- Filter added for richfaces --> <filter> <display-name>RichFaces Filter</display-name> <filter-name>richfaces</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>richfaces</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> …
Maintenant afin ajouter dans notre page un composant que je trouve assez sympa sur richfaces, le calendar, nous devons ajouter une taglib à celui-ci :
<%@taglib uri=”http://richfaces.org/rich” prefix=”rich”%>
Et maintenant, afin d’afficher le calendar dans la page JSF, nous ajouterons :
… <f:view> … <rich:calendar></rich:calendar> … </f:view> …
Je vous invite à consulter le 3 ème lien en référence afin de voir la démo de ce que l’on peut faire avec richfaces Accès au code source :
Le code source complet est disponible ici :
- http://www.cestpasdur.com/svn/webapp-maven-jsf/trunk/
- login : anonymous
- mot de passe : guest
- copie en ligne de commande : svn co http://www.cestpasdur.com/svn/webapp-maven-jsf/trunk/
Références :
http://www.lulu.com/items/volume_62/1080000/1080910/2/print/Java-Maven-Eclipse-JSF-Tutorial.pdf
http://www.exadel.com/tutorial/jsf/jsftutorial-kickstart.html
http://livedemo.exadel.com/richfaces-demo/index.jsp
JMX, supervision et administration des applications J2EE
Java Management eXtension ou JMX est une API java permettant de surveiller une application existante. Cette technologie permet également d’intéragir sur l’application en cours d’exécution. Cette API a été intégré dans le J2SE à partir de la version 1.5. Dans l’exemple ci-dessous, nous utiliserons cette technologie afin de suivre le nombre d’objets mis en cache avec EHCache et JMX.
Acquisition de données (instrumentation) avec JMX
Le MBean (managed bean) est l’élément de base de JMX. Associé à un agent de supervision, il servira d’interface de communication avec les éléments gérés par JMX. On peut le voir comme une sonde effectuant une ou plusieurs mesures.
MBeanServer : l’agent de Supervision
Appelés agents ou serveurs JMX, ceux-ci sont chargés de recenser les MBeans. Chaque ajout ou supression d’un MBean donne lieu à une notification.
Spring et JMX
Comme à son habitude, Spring facilite l’intégration de JMX dans l’architecture d’une application. Il met à disposition des méthodes simples pour enregistrer de nouveaux MBean. Cette intégration se fait tout en conservant un faible couplage de l’application avec cette technologie.
Suivi des objets en cache avec EHCACHE et JMX dans une application SPRING
Afin de faciliter la mise en place de cette technologie, nous nous baserons sur une application fonctionnant sur le serveur d’application JBOSS.
Nous allons mettre un place un MBean qui effectuera un certain nombre de mesures afin de suivre l’évolution de la propriété MemoryStoreSize de notre cache.
Configuration Spring du MBean :
<bean id="jmxCacheBean" class="com.programmetvcesoir.jmx.JmxCache"> <property name="cacheManager" ref="cacheManagerID"></property> </bean>
La classe correspondante :
mport net.sf.ehcache.Cache ;
import net.sf.ehcache.CacheManager;
/**
* MBean permettant de surveiller et d‘adminitrer via jmx le cache géré par EHCACHE
* @author dgouyette
*
*/
public class JmxCache
/**
* Manager de cache EHCACHE
*/
private CacheManager cacheManager ;
public JmxCache()
{
}
public long getMemoryStoreSize()
{
Cache cache=cacheManager.getCache("1000_overflow_disk") ;
return cache.getMemoryStoreSize() ;
}
public void removeAll()
{
Cache cache=cacheManager.getCache("1000_overflow_disk") ;
cache.removeAll() ;
}
public void setCacheManager(CacheManager cacheManager)
{
this.cacheManager = cacheManager ;
}
Comme vous pouvez le voir, la valeur de la propriété cacheManager est injectée via la configuration Spring. Nous avons donc accès dans notre MBean à l’ensemble des propriétés du cacheManager, en l’occurence celle qui nous intéresse : memoryStoreSize (nombre d’objet en cache à un instant T). Maintenant, notre MBean a besoin de communiquer avec un MBeanServer. La configuration suivante permet de localiser un server existant et de s’y connecter (dans notre cas, JBoss)
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"> <property name="locateExistingServerIfPossible" value="true"/> </bean>
C’est aussi simple que çà ! Notre MBean va devoir notifier sa présence au MBeanServer en utilisant un MBeanExporter :
<bean id="exporter"class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=jmxCacheBean" value-ref="jmxCacheBean"></entry>
</map>
</property>
<property name="server" ref="mbeanServer"/>
</bean>
Au démarrage du serveur, nous pouvons voir la présence du MBean dans les logs :
DEBUG org.springframework.jmx.support.JmxUtils - Found MBeanServer : org.jboss.mx.server.MBeanServerImpl@1c9a690[defaultDomain='jboss' ] INFO org.springframework.jmx.export.MBeanExporter - Registering beans for JMX exposure on startup DEBUG org.springframework.jmx.export.MBeanExporter - Located simple bean ‘bean:name=jmxCacheBean’ : registering with JMX server as MBean [bean:name=jmxCacheBean]
Essayez maintenant avec la console web JMX de JBoss.
Vous pouvez constater que notre MBean est bien référencé sur le serveur d’applications. Maintenant une console JMX un peu plus pratique serait sympa, vous avez la JConsole disponible via le jdk, dans mon cas c’est ici : c :\Program Files\Java\jdk1.6.0_03\bin\jconsole.exe ou bien vous pouvez télécharger la MC4J management console.
J’espère que cette petite introduction aux extensions JMX vous a permis de comprendre ce qu’est JMX, et, d’en cerner un peu plus l’utilité.
JBOSS SEAM, premiers pas (getting started)
Un tutoriel dans la lignée des step by step de spring afin de créer sa première application fonctionnant avec jboss Seam.
Installation
Prérequis : avoir un jdk 5 ou 6 installé sur la machine.
Téléchargez JBOSS Seam (version 2.0.2, au jour d’aujourd’hui, la version 2.1 (en développement) me retourne une exception ant à la création d’un nouveau projet) Téléchargez JBOSS AS 4.2.2.GA Téléchargez ANT 1.7.0
Extraire JBOSS SEAM dans le répertoire C :\java\jboss-seam-2.0.2.GA\ Extraire JBOSS AS dans le répertoire C :\java\jboss-4.2.2.GA\ Extraire ANT 1.7 dans le répertoire c :\java\ant-1.7.0\
Ajouter ces répertoires dans le path :
c :\java\ant-1.7.0\bin\
C :\java\jboss-seam-2.0.2.GA\
Cliquez sur Ok
fin de valider que cette modification soit prise en compte tapez la commande
seam help
Vous devriez voir défiler l’ensemble des commandes disponibles, dans le cas contraire vérifiez l’emplacement du répertoire jboss seam ainsi que son paramétrage dans le path windows
Modifier le fichier C :\java\jboss-seam-2.0.2.GA\build.properties présent dans le répertoire afin de le faire pointer sur l’emplacement du serveur d’application jboss, mettez bien les slash dans ce sens, sinon cela ne fonctionnera pas.
boss.home=C:/java/jboss-4.2.2.GA/
Faire fonctionner les exemples
Avant d’écrire le moindre bout de code, il peut être intéressant de tester les exemples fournis (26) avec le framework. Démarrer le serveur jboss avec la commande :
C:\java\jboss-4.2.2.GA\bin\>run.bat
Ensuite il faut lancer la tache ant correspondante, pour le blog par exemple :
C:\java\jboss-seam-2.0.2.GA\examples\blog>ant deploy
Pour info, le mot de passe pour se logger au blog est tokio normalement vous devriez voir le blog à l’adresse suivante : http://localhost:8080/seam-blog/
Dans l’ensemble les démos fonctionnaient bien. Les fonctionnalités présentes dans ces applications seront certainement d’une grande aide à l’apprentissage du framework.
Bon point pour Redhat de fournir toutes ces démos
JBOSS SEAM, création du premier projet HelloWorld
Après avoir effectué la configuration de l’environnement permettant de faire fonctionner le framework JBoss seam dans le l’article Jboss seam premier pas getting started, nous allons maintenant pouvoir créer notre premier projet.
Configuration de l’environnement avec seam setup
C:\>seam setup Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre1.6.0_04\lib\tools.jar Buildfile: C:\java\jboss-seam-2.0.1.GA\seam-gen\build.xml init: setup: [echo] Welcome to seam-gen[input] Enter your Java project workspace (the directory that contains your Seam projects) [C:/Projects] [C:/Projects] C:\java\workspace [input] Enter your JBoss home directory [C:/Program Files/jboss-4.2.2.GA] [C:/Program Files/jboss-4.2.2.GA] C:\java\jboss-4.2.2.GA [input] Enter the project name [myproject] [myproject] HelloWorld [echo] Accepted project name as: HelloWorld [input] Do you want to use ICEFaces instead of RichFaces [n] (y, [n], ) n [input] skipping input as property icefaces.home.new has already been set. [input] Select a RichFaces skin [blueSky] ([blueSky], classic, ruby, wine, deepMarine, emeraldTown, sakura, DEFAULT) ruby [input] Is this project deployed as an EAR (with EJB components) or a WAR (with no EJB support) [ear] ([ear], war, ) war (ca fait riche un ear pour faire un hello world) [input] Enter the Java package name for your session beans [com.mydomain.HelloWorld] [com.mydomain.HelloWorld] [input] Enter the Java package name for your entity beans [com.mydomain.HelloWorld] [com.mydomain.HelloWorld] [input] Enter the Java package name for your test cases [com.mydomain.HelloWorld.test][com.mydomain.HelloWorld.test] [input] What kind of database are you using? [hsql] ([hsql], mysql, oracle, postgres, mssql, db2, sybase, enterprisedb, h2) [input] Enter the Hibernate dialect for your database [org.hibernate.dialect.HSQLDialect] [org.hibernate.dialect.HSQLDialect] [input] Enter the filesystem path to the JDBC driver jar [lib/hsqldb.jar] [lib/hsqldb.jar] C:\java\jboss-4.2.2.GA\server\all\lib\hsqldb.jar [input] Enter JDBC driver class for your database [org.hsqldb.jdbcDriver] [org.hsqldb.jdbcDriver] [input] Enter the JDBC URL for your database [jdbc:hsqldb:.] [jdbc:hsqldb:.] jdbc:hsqldb:mem:helloWorldDb [input] Enter database username [sa] [sa] [input] Enter database password [] [] [input] Enter the database schema name (it is OK to leave this blank) [] [] [input] Enter the database catalog name (it is OK to leave this blank) [] [] [input] Are you working with tables that already exist in the database? [n] (y, [n], ) [input] Do you want to drop and recreate the database tables and data in import.sql each time you deploy? [n] (y, [n], ) y [propertyfile] Creating new property file: C:\java\jboss-seam-2.0.1.GA\seam-gen\build.properties [echo] Installing JDBC driver jar to JBoss server [echo] Type ’seam create-project’ to create the new project BUILD SUCCESSFUL Total time: 3 minutes 16 seconds C:\>
Création d’un nouveau projet avec seam new-project
Voilà notre premier projet configuré, maintenant il faut le créer avec la commande :
seam new-project
La structure du projet a été créée dans le workspace indiqué précédement. Les jars seam vont y être copiés, les templates facelets, les métédatas Eclipse, les scripts de build Ant.
Copier le war explosé dans le répertoire adéquat du serveur jboss avec la commande :
seam explode
Importer et démarrer l’application dans JBOSS TOOLS
Afin de pouvoir modifier les fichiers dans l’IDE, il faut :
File > new > Project > sélectionnez Général > Project (ne pas sélectionner projet java) Project name : helloworld
Maintenant afin de voir les traces dans la console eclipse, nous allons ajouter dans la view server, notre serveur jboss : Windows > show view > sélectionnez servers
Dans la vue nouvellement ouverte, clic droit new server et sélectionnez le server JBOSS AS 4.2 Cliquez sur next Home directory : C :\java\jboss-4.2.2.GA Choisissez le serveur default et cliquez sur finish Maintenant démarrez le serveur nouvelle ajouté, si vous regardez bien la console, vous verrez l’application helloworld démarrer. Afficher dans votre navigateur http://localhost:8080/helloworld/ Afin de tester une fonctionnalité intéressant de JBOSS :
Modifiez par exemple de fichier web.xml se trouvant dans ressources > WEB-INF Modifiez la valeur du noeud
<context-param> <param-name>org.richfaces.SKIN</param-name> <param-value>ruby</param-value> </context-param>
par
<context-param> <param-name>org.richfaces.SKIN</param-name> <param-value> pop </param-value> </context-param>
Lorsque vous allez sauvegarder vos modifications, observez la console
on peut observer que le fichier modifié a directement été copié dans :
[copy] Copying 3 files to Y:\java\jboss-4.2.2.GA\server\default\deploy\helloworld.war
Et que sans redémarrer votre serveur, la modification a été prise en compte. Que de temps gagné (ceux qui ont codé sur des gros projets avec maven, spring et Eclipse me comprendront), raffraichissez votre page et observez le nouveau thème appliqué au projet :
Création de la page helloWorld
Nous allons pour cela créer unenouvelle action avec la commande :
eam new-action C:\dev\projects>seam new-action Buildfile: C:\java\jboss-seam-2.0.1.GA\seam-gen\build.xml init: init-properties: [echo] C:/java/jboss-4.2.2.GA validate-workspace: validate-project: action-input: [input] Enter the Seam component name sayHelloWorld [input] Enter the local interface name [SayHelloWorld] [SayHelloWorld] [input] Enter the bean class name [SayHelloWorldBean] [SayHelloWorldBean] [input] Enter the action method name [sayHelloWorld] [sayHelloWorld] [input] Enter the page name [sayHelloWorld] [sayHelloWorld] setup-filters: new-action-ear: new-action-war: [echo] Creating a new JavaBean component with an action method [copy] Copying 1 file to C:\java\workspace\HelloWorld\src\action\com\mydomain\HelloWorld [copy] Copying 1 file to C:\java\workspace\HelloWorld\src\test\com\mydomain\HelloWorld\test [copy] Copying 1 file to C:\java\workspace\HelloWorld\src\test\com\mydomain\HelloWorld\test [copy] Copying 1 file to C:\java\workspace\HelloWorld\view [echo] Type ’seam explode’ and go to http://localhost:8080/HelloWorld/sayHelloWorld.seam new-action: BUILD SUCCESSFUL Total time: 31 seconds C:\dev\projects>
Création de la page helloWorld
La création d’une action nécessite de redémarrer le serveur, faites le avec la commande :
seam restart
Votre serveur d’application devrait redéployer tout seul l’application helloworld
Afin de voir notre helloworld, il suffit maintenant d’afficher la page http://localhost:8080/HelloWorld/sayHelloWorld.seam
Afin que l’application fasse ce qu’on lui demande, c’est à dire “dire bonjour”, il ne vous reste plus qu’a cliquer sur le bouton sayHelloWorld qui lancera la méthode sayHelloWorld de l’action que nous venons de créer.
...
public void sayHelloWorld()
{
//implement your business logic here
log.info(”sayHelloWorld.sayHelloWorld() action called”);
facesMessages.add(”sayHelloWorld”);
}
...
Webapp avec maven, JSF, facelets
Ce tutorial est dans la logique des précédents. Nous allons ajouter une difficulté supplémentaire qui vous permettra ensuite d’utiliser les fonctionnalités puissantes de templating. Maintenant que j’y ai goûté, j’aurais du mal à m’en passer.
Code
Ajouter dans le pom du war
<!-- Dependances facelets -–> <dependency> <groupId>com.sun.facelets</groupId> <artifactId>jsf-facelets</artifactId> <version>1.1.9</version> </dependency>
Entêtes des pages xhtml
Toutes les pages xhtml étant du xml, si vous souhaitez utiliser des taglibs au sein de cell-ci, il va falloir les déclarer, mais pas de la manière habituelle utilisée dans les JSP (non valide xml)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
Ajout dans le faces-config.xml, celui ci indique que facelets est défini comme gestionnaire de vue.
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
L’élèment html est utilisé pour déclarer tous les namespaces. L’exemple indiqué est loin d’être exaustif. Pour info, cette notation et prise en compte différement selon l’IDE. MyEclipse (dans sa version 6) ne le comprend pas. Je vous conseille d’utiliser jboss-tools, surtout si vous voulez ensuite utiliser les librairies de richfaces.
Découpage des pages web en templates & includes
- default.jsp : page de redirection
- index.xhtml page “templatées” que nous souhaitons afficher
- Layout.xhtml : template de page mettant en place les includes ci-dessous
- header.xhtml : entête de page réutilisable
- menu.xhtml : menu réutilisable
- footer.xhtml : pied de page réutilisables
Index.xhtml
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.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”>
<ui:composition template=”/WEB-INF/templates/layout.xhtml”>
<ui:define name=”titre”>Tutorial facelets</ui:define>
<p><strong>Appel au managed bean : <h:outputText
value=”#{serieBean.test}”></h:outputText></strong></p>
<ui:define name=”contenu”>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Nulla erat. Proin augue metus, vulputate at, ullamcorper eu, accumsan non, leo. Sed eu magna nec massa consectetuer consequat. Mauris ipsum dolor, ullamcorper sed, lacinia eget, sagittis non, mauris. Sed molestie, augue id fermentum consequat, nibh tellus fermentum est, id gravida nunc nisi in diam. Vestibulum eu dui sed nibh posuere faucibus. Donec tristique elementum leo. Integer tellus. Nunc malesuada eros non purus. Mauris ac lectus. Proin venenatis libero vel eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin tortor turpis, elementum a, ornare in, vulputate eget, tellus. </ui:define>
</ui:composition>
</html>
ui:composition va spécifier le template que nous allons utiliser
ui:define transmet à ce layout une valeur qui va pouvoir utiliser pour valoriser la variable associée
Layout.xhtml
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” xmlns:ui=”http://java.sun.com/jsf/facelets”> <head> <title><ui:insert name=”titre”>Default title</ui:insert></title> </head> <body> <ui:include src="header.xhtml"/> <ui:include src="menu.xhtml"/> <div id=”contenu”><ui:insert name=”contenu”> </ui:insert></div> <ui:include src=”footer.xhtml”/> </body> </html>
ui:include comme vous l’aurez compris est un simple include (mais doit rester valide xml)
ui:insert est associé à un:define, celui ci va réutiliser la variable fournie, et l’afficher.
Accès au code source :
Le code source de l’application est disponible ici :
http://www.cestpasdur.com/svn/webapp-maven-jsf-facelets/trunk/
Références
https://facelets.dev.java.net/nonav/docs/dev/docbook.html
http://www-128.ibm.com/developerworks/java/library/j-facelets/