Parce que c’est l’été, qu’il fait chaud, et que depuis 4 mois je ne parle QUE de Play! Framework, après ne vous avoir parlé QUE de Grails cet hiver, je me suis dis qu’il était temps de parler un peu de JavaServer Faces et de tester NetBeans 6.9. D’ici quelques minutes vous serez en mesure de construire une application type CRUD (Create, Update, Research, Update and Delete) avec JSF 2, un bean Stateless Java EE 6 et une entité JPA.
Pour vous accompagner durant ce vol, installez vous confortablement, prenez le pack de 178Mo de NetBeans 6.9 pour ne pas perdre de temps avec un IDE des années 90, et en avant l’aventure.
Ce que je souhaite faire, c’est vous montrer comment écrire en quelques minutes une application Web légère, à la mode de Play! Framework, mais en travaillant avec Java EE 6.
Une fois NetBeans démarré, créez un nouveau projet, et sélectionnez « Java Web/Web Application ».
(Cliquez sur l’image ci-dessous pour l’afficher en grand)
Je garde le nom proposé par NetBeans de « WebApplication1 », je décide d’utiliser le serveur GlassFish et d’utiliser Java EE 6. Ecran suivant, j’active Hibernate et JSF2 car nous allons en avoir besoin dans quelques minutes.
(Cliquez sur l’images pour l’afficher en grand… oui je l’ai déjà dit ci-dessus)
L’environnement est pré-configuré avec une base Apache Derby.
Cliquez sur Finish, NetBeans créé un projet prêt à être déployé.
Générer une Entité, un Controleur et une Facade
Je vous propose de vous montrer comment générer des pages type CRUD en quelques minutes, le tout avec NetBeans, sans taper une ligne de code.
Dans l’onglet « Services » en haut à gauche, cliquez sur Databases > jdbc:derby://localhost:1527/sample. Clique droit, et sélectionnez Connect… Vous verrez alors différents catalogues. Sélectionnez « APP », puis dans Table vous verrez qu’il y a plusieurs Tables préconfigurées : CUSTOMER, DISCOUNT_CODE, et d’autres. Nous avons donc de quoi générer des Entités.
Cliquez sur l’onglet « Projects » en haut à droite, puis sur le répertoire « Source Packages », faites un clique droit sur ce répertoire pour sélectionner ensuite « Entity Classes from Database » dans le menu contextuel :
Après avoir sélectionné « jdbc/sample » dans la liste DataSource, sélectionnez une des Tables. J’ai pris MICRO_MARKET. Sur l’écran suivant, créez un package org.letouilleur.demo puis cliquez sur « Finish ». Le code de l’Entité généré est très complet :
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.letouilleur.demo; import java.io.Serializable; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; /** * * @author nicolas */ @Entity @Table(name = "MICRO_MARKET") @NamedQueries({ @NamedQuery(name = "MicroMarket.findAll", query = "SELECT m FROM MicroMarket m"), @NamedQuery(name = "MicroMarket.findByZipCode", query = "SELECT m FROM MicroMarket m WHERE m.zipCode = :zipCode"), @NamedQuery(name = "MicroMarket.findByRadius", query = "SELECT m FROM MicroMarket m WHERE m.radius = :radius"), @NamedQuery(name = "MicroMarket.findByAreaLength", query = "SELECT m FROM MicroMarket m WHERE m.areaLength = :areaLength"), @NamedQuery(name = "MicroMarket.findByAreaWidth", query = "SELECT m FROM MicroMarket m WHERE m.areaWidth = :areaWidth")}) public class MicroMarket implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "ZIP_CODE") private String zipCode; @Column(name = "RADIUS") private Double radius; @Column(name = "AREA_LENGTH") private Double areaLength; @Column(name = "AREA_WIDTH") private Double areaWidth; public MicroMarket() { } public MicroMarket(String zipCode) { this.zipCode = zipCode; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } public Double getRadius() { return radius; } public void setRadius(Double radius) { this.radius = radius; } public Double getAreaLength() { return areaLength; } public void setAreaLength(Double areaLength) { this.areaLength = areaLength; } public Double getAreaWidth() { return areaWidth; } public void setAreaWidth(Double areaWidth) { this.areaWidth = areaWidth; } @Override public int hashCode() { int hash = 0; hash += (zipCode != null ? zipCode.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof MicroMarket)) { return false; } MicroMarket other = (MicroMarket) object; if ((this.zipCode == null && other.zipCode != null) || (this.zipCode != null && !this.zipCode.equals(other.zipCode))) { return false; } return true; } @Override public String toString() { return "org.letouilleur.demo.MicroMarket[zipCode=" + zipCode + "]"; } }
La Table Micro_Market a pour PRIMARY_KEY une clé technique de type NUMERIC. Comme je le disais sur Twitter hier soir, NetBeans 6.9 génère les méthodes hashCode() et equals() en se basant sur l’id technique, pour peu évidemment qu’il soit présent. Moi je trouve que c’est une bonne chose.
J’en ai parlé en 2009 lorsque j’avais testé SpringFuse et plus récemment dans un article en juin, peut-être pas assez complet je pense.
Générer des pages CRUD avec JSF 2.0
Pour continuer, voyons comment générer quelques pages comme list, create, edit et delete avec JSF. L’approche proposée par NetBeans est simple, elle utilise une Facade sous la forme d’un EJB Stateless et un Controleur, sous la forme d’un ManagedBean.
Cliquons à nouveau sur le répertoire « Source Package » et sélectionnons « New>JSF Pages from Entity Classes ». Sélectionnez alors votre entité, puis sur l’écran suivant précisez où vous souhaitez stocker la partie Session, les pages JSF et enfin le répertoire pour les pages. Dans la zone JSP Pages Folder je n’ai rien précisé.
NetBeans génère une Facade, un Contrôleur et quelques pages JSF. Je vous présenterai les différences d’approche entre la version JSF 2 et une version Play! Framework dans un deuxième article.
Test final
Il est temps de démarrer le serveur et de tester. Cliquez sur « Run Main Projet » (F6). GlassFish se lance rapidement et la page d’accueil permet de sélectionner l’option »
En quelques minutes, NetBeans génère un petit projet complet avec une Entity, une partie JSF simple, et quelques pages type CRUD, ce qui donne une bonne base de départ. J’aime l’aspect couteau-suisse de NetBeans : simple, propre, facile à mettre en oeuvre. Pour débuter avec Java EE 6, je pense que c’est un bon outil, qui permet d’aller à l’essentiel sans perdre de temps à installer ou configurer quoique ce soit.
A tester donc !
Dans le prochain article : comparaison de l’approche JSF 2 par rapport à Play! Framework
Références
Introduction to JavaServer Faces 2.0 with NetBeans
« … pour ne pas perdre de temps avec un IDE des années 90 … »
Une attaque contre Eclipse ?
Ce que je ne comprends pas c’est le rapport entre ce générateur et NetBeans.
Un générateur de code n’a pas à être lié à un IDE, non ?
Je pense que Nicolas fait référence aux capacités « out of the box » de l’IDE: runtime, support JSF 2 (et Java EE 6 complet). La version « Java », un peu plus légère fait aussi l’affaire.
Merci pour cet article, je n’avais pas encore eu l’occasion d’utiliser netbeans 6.9.
Pour la génération de code, pour une fois, ce n’est pas du code simpliste qui est généré :
– gestion de la pagination,
– equals /hashcode
Je pense qu’ils auraient pu continuer a abstraire certaines notions transverses sur les managedBean comme ils l’ont fait sur la facade, mais comme tu l’as dit le code généré est très complet.
Dommage également que le projet ne soit pas mavenisé
J’attends avec impatience ton article sur JSF2/Play, étant fan des 2 technologies
Article intéressant!
Étant moi-même en train d’explorer JEE 6 et les JavaServer Faces, je me suis empressés de suivre ce tuto. NetBeans est bluffant pour le coup.
A noter que le code généré fonctionne (presque) en utilisant les annotations proposé par CDI (JSR 299) sur GlassFish:
– @Named (javax.inject) au lieu de @ManagedBean
– @SessionScope du paquetage javax.enterprise.context
=> Faut simplement ajouter « implements Serializable » à la classe MicroMarketController
Bonjour,
Personnellement j’aurais beaucoup apprécié voir ce même tuto porté sur un éditeur des années 90, parlons sans tabous : Eclipse.
Netbeans est certes très pratique pour générer plein de choses tout seul, mais ce n’est à mon avis pas la meilleure manière d’apprendre. Je suis sur Eclipse, ayant une bonne expérience en J2SE, et essayant de me familiariser avec JEE-6 dont les JSF. Résultat des courses : on ne voit pas comment les données sont transférées de la base à la page web ou encore comment sont appelées les méthodes, malgré le fait que vos explications soient très claires.
Je trouve dommage que le net et la librairie JEE regorge autant d’exemples pour Netbeans et si peu pour Eclipse (mais là n’est pas le sujet).
Merci cependant pour cet article très bien écrit.
Je trouve également un peu dommage que la génération de code soit si fortement câblée au sein de l’IDE. Un générateur basé sur le moteur de templates de Groovy avec la possibilité d’éditer les templates (sans forcément aller jusqu’à pouvoir maitriser la chaine de production comme dans Acceleo) aurait vraiment été top.
Merci pour le post.
De gros progès côté Glassfish donc, confirmé par la facilité à mettre en oeuvre un projet JSF2.0 – EJB3.1 mavenisé et déployable sous Glassfish 3.
C’est JEE dans son ensemble qui progresse en fait, car le même projet se déploit aussi sous Jboss6.
Et le pom.xml fait à peine une 20aine de lignes.