Accéder au contenu principal

Atelier JSF EJB

Introduction

Dans cet atelier nous mettons en avant les technologies JSF, EJB, JPA pour réaliser un projet Java EE qui consiste à créer une seule entité “Article” et interagir avec moyennant les deux opérations d’ajout et d’affichage. Dans ce projet, la couche web est illustrée par la technologie JSF, la couche métier est représentée par la technologie EJB et la couche de persistence est représentée par la technologie JPA. La base de données est assurée par derby, l’IDE utilisé est NetBeans version Java EE. Pour des soucis liés au temps, nous avons fait appel pour certains passages à la génération automatique du code. 

Architecture du projet

Tout d’abord, l’architecture du projet se présente comme suit :

Architecture du projet
Architecture du Projet

Nous avons d’abord un dossier “resources” (un seul ‘s’ pour avoir de la compatibilité avec les projets Java EE à l’échelle internationale) qui contient deux sous dossiers : css et images. Ce dernier contiendra toutes les images nécessaires à l’élaboration de notre projet, tandis que le dossier css contiendra toutes les feuilles de style propres à notre projet.
La partie Web (dossier Web Pages) est représentée par deux pages jsf : Home et AjouterArticle. La première c’est une sorte de page d’accueil du site, la deuxième contient les liens pour activer simultanément l’ajout et l’affichage des articles au niveau de la base de données.
La partie Java est répartie en trois packages. Le premier package ‘org.cours.entites’ contient toutes les classes entités du projet, dans notre cas il s’agit de l’entité ‘Article’ qui ne contient que les champs représentés dans la base de données, à savoir : id, nom et prix. Le deuxième package “org.cours.dao’ contient la classe EJB, qui dans notre cas ayant utilisé le pattern Facade va être illustrée par trois classes : AbstractFacade, AbstractFacadeLocal et ArticleFacade. Le trosième package “org.cours.beans” contient les classes de type Managed Bean du projet, dans notre cas il s’agit d’une seule Managed Bean : ‘ArticleBean’ qui va assurer le rôle d'intermédiaire entre le formulaire JSF et la classe EJB.

La couche Web

Dans cette couche, on aura besoin de deux pages JSF, l’une c’est la page d’accueil “Home.xhtml”, et l’autre c’est la page “AjouterArticle.xhtml” qui va nous permettre d’ajouter et de consulter les articles de la base.
Pour créer la page JSF “Home.xhtml”, on fait bouton droit sur le projet ensuite on choisit la catégorie Java Server Faces et on sélectionne à droite “Facelets Template” comme suit :

Template Facelet Creation
Création de la template Facelet

On appuie sur Next, et puis on donne le nom “Home” à cette page tout en sélectionnant en bas le type de template, comme suit :

Style de la template
Choix du style de la template

Après on modifie les rubriques “top”, “left” et “content” ci dessous (l’image il faut la télécharger et la placer dans le sous-dossier “images” du dossier “resources” pour pouvoir l’utiliser) :

Home.xhtml

<?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">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
          xmlns:h="http://xmlns.jcp.org/jsf/html">
        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <h:outputStylesheet name="css/default.css"/>
            <h:outputStylesheet name="css/cssLayout.css"/>
            <title>Ventes AKYA MEDIA</title>
        </h:head>
        <h:body>
            <div id="top">
                <ui:insert name="top"><h1 align="center">Gestion des Ventes</h1></ui:insert>
            </div>
            <div>
                <div id="left">
                    <ui:insert name="left">
                        <a href="AjouterArticle.xhtml">Gestion Articles</a>
                    </ui:insert>
                </div>
                <div>
                    <div id="content" class="right_content">
                        <ui:insert name="content">
                            <h:graphicImage library="images" name="logo.png" width="50%" height="50%" />
                        </ui:insert>
                    </div>
                </div>
            </div>       
        </h:body>
</html>

La page “AjouterArticle.xhtml” va ensuite être créée à base de la template “Home.xhtml”. On fait bouton droit sur le projet, catégorie “Java Server Faces” et on choisit “Facelets Template Client” :

Template client
Création de la template Client



On appuie sur Next et on saisie le nom de la page “AjouterArticle”:

La page ajouterArticle.xhtml
La page ajouterArticle.xhtml



Il reste à définir la template, pour cela on clique sur le bouton ‘Browse…’ en face de ‘Template’ :



Template de base
Choix de la template de base


On choisit le nom de la template “Home.xhtml” et on appuie sur “Select File”.On aura alors la page suivante qu’on va personnaliser en définissant la rubrique “content” au niveau de la page comme ci dessous :

AjouterArticle.xhtml

<?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">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<body>
<ui:composition template="./Home.xhtml">

<ui:define name="top">
<h1 align="center">Gestion Articles</h1>
</ui:define>
<ui:define name="left">
<a href="AjouterArticle.xhtml">Gestion Articles</a>
</ui:define>
<ui:define name="content">
<f:view>
<h:form>
<h1>Ajout Produit</h1>
<h:panelGrid columns="2">
<h:outputText value="Code"/>
<h:inputText />
<h:outputText value="Libelle"/>
<h:inputText />
<h:outputText value="Prix"/>
<h:inputText />
<h:commandButton value="Ajouter" />
</h:panelGrid>
</h:form>
</f:view>
</ui:define>
</ui:composition>
</body>
</html>

Pool de connexion

Maintenant, en supposant que la base de données “com” est déjà créée ainsi que la table Produit (id, libelle, prix), nous procédons à la création du pool de connexion. En cliquant avec le bouton droit sur le nom du projet, on choisit la catégorie “GlassFish” et on sélectionne le type “JDBC Connection Pool”, après on appuie sur “Next”.

JDBC connection pool
JDBC connection pool

 
Dans le champ “JDBC Connection Pool Name” on saisit un nom, par exemple “gcom”, et en bas on sélectionne notre base de données “com” comme suit :

Choix de la base de données
Choix de la base de données


Et ensuite on valide le reste en cliquant successivement sur “Next”.
Après cette opération, on va créer la ressource JDBC. On appuie avec le bouton droit sur le nom du projet, on choisit la catégorie “GlassFish” et on sélectionne le type “JDBC Resource” :



Ressource JDBC
La ressource JDBC

Nous sélectionnons après le nom du pool de connexion “gcom” créée précédemment :

Pool de connexion JDBC
Choix du pool de connexion JDBC


Après on valide la création en cliquant sur “Next” puis “Finish”.

Création de la classe Entité

A ce niveau, nous allons créer la classe entité “Article.java”. Pour ce faire, nous cliquons avec le bouton droit sur le nom du projet, dans la catégorie “Persistence”, nous choisissons le type “Entity Classes from Database” :


Création de l'Entité Classe
Création de l'Entité Classe


Nous appuyons sur “Next”, ensuite nous choisissons notre “Data Source” ainsi que la table “Article” qu’on va ajouter à droite en appuyant sur le bouton “Add >” :

Choix de la Data Source
Choix de la Data Source

 Après on valide en cliquant sur “Next” pour avoir la fenêtre suivante :


Création de l'Entité Classe
Création de l'Entité Classe


Nous choisissons le nom “org.cours.entites” par exemple et on valide. Nous obtiendrons la classe “Article.java” avec le code généré automatiquement comme suit :

Article.java

package org.cours.entites;
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;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name = "ARTICLE")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Article.findAll", query = "SELECT a FROM Article a")
, @NamedQuery(name = "Article.findById", query = "SELECT a FROM Article a WHERE a.id = :id")
, @NamedQuery(name = "Article.findByLibelle", query = "SELECT a FROM Article a WHERE a.libelle = :libelle")
, @NamedQuery(name = "Article.findByPrix", query = "SELECT a FROM Article a WHERE a.prix = :prix")})
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "ID")
private Long id;
@Size(max = 255)
@Column(name = "LIBELLE")
private String libelle;
// @Max(value=?) @Min(value=?)

@Column(name = "PRIX")
private Double prix;

public Article() {
}

public Article(Long id) {
this.id = id;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getLibelle() {
return libelle;
}

public void setLibelle(String libelle) {
this.libelle = libelle;
}

public Double getPrix() {
return prix;
}

public void setPrix(Double prix) {
this.prix = prix;
}

@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Article)) {
return false;
}
Article other = (Article) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}

@Override
public String toString() {
return "org.cours.entites.Article[ id=" + id + " ]";
}
}

Session Bean

Dans cette partie nous allons créer la session bean pour gérer la communication entre la classe entité “Article” et la la base de données.
On clique avec le bouton droit sur le nom du projet, on choisit la catégorie “Entreprise JavaBean” puis le type “Session Bean For Entity Classes” :


Création de la SessionBean
Création de la session Bean


On clique sur Next et on choisit la classe entite “Article” ensuite on appuie sur le bouton “Add >” pour l’ajouter :


SessionBean pour la classe Entité
Session Bean pour la classe entité



On choisit après le package “org.cours.dao” par exemple et on coche la case “Locale” puis on valide :
Interface Locale
Interface Locale

 


On obtendra trois classes “AbstractFacade.java”, “ArticleFacade.java” et “ArticleFacadeLocal.java” qui sont générés automatiquement selon le design pattern “Facade” et qui vont assurer le rôle d’interfacage avec l’entité “Article” et la table “Article” de la base de données.

La Managed Bean

Maintenant nous créons la managed bean Jsf qui va communiquer entre la page JSF de saisie des données de l’article et la classe “ArticleFacade.java”. Pour ce faire, on clique avec le bouton droit sur le nom du projet, on choisit la catégorie JSF ensuite le type “JSF Managed Bean” et on appuie sur “Next” :

ManagedBean
Création de la ManagedBean


On donne un nom à la classe, par exemple “ArticleBean” et on choisit le package “org.cours.beans” comme suit :

JSF ManagedBean
La JSF ManagedBean


Et on clique sur le bouton “Finish”. On obtient alors la classe “ArticleBean.java” que nous allons modifier en ajoutant la portion de code en couleur bleu ainsi que les getters et setters pour l’avoir comme suit :

ArticleBean.java

package org.cours.beans;
import java.util.List;
import org.cours.dao.ArticleFacadeLocal;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.cours.entites.Article;
@ManagedBean
@RequestScoped
public class ArticleBean {
@EJB
private ArticleFacadeLocal articleFacade;
private Article article = new Article();
private String resultat; //message de confirmation d’ajout d’un article
public void ajouterArticle(){
articleFacade.create(article);
this.resultat = "Article ajouté avec succès...!!!";
}
public List<Article> afficherArticles(){
return articleFacade.findAll();
}
public ArticleBean() {
}
public ArticleFacadeLocal getArticleFacade() {
return articleFacade;
}
public void setArticleFacade(ArticleFacadeLocal articleFacade) {
this.articleFacade = articleFacade;
}
public Article getArticle() {
return article;
}
public void setArticle(Article article) {
this.article = article;
}
public String getResultat() {
return resultat;
}
public void setResultat(String resultat) {
this.resultat = resultat;
}
}

Modification de “AjouterArticle.xhtml”

Pour relier les champs de saisie de la page “AjouterArticle.xhtml” avec ceux de la managed bean “ArticleBean.java” nous allons apporter les changements suivants à la page “AjouterArticle.xhtml” comme ci dessous :


<ui:define name="content">
<f:view>
<h:form>
<h1>Ajout Produit</h1>
<h:panelGrid columns="2">
<h:outputText value="Code"/>
<h:inputText value="#{articleBean.article.id}"/>
<h:outputText value="Libelle"/>
<h:inputText value="#{articleBean.article.libelle}" />
<h:outputText value="Prix"/>
<h:inputText value="#{articleBean.article.prix}" />
<h:commandButton value="Ajouter" action="#{articleBean.ajouterArticle()}"/>
</h:panelGrid>
<h:outputText style="color: greenyellow" value="#{articleBean.resultat}" />
</h:form>
<h:form>
<h1><h:outputText value="Liste des Articles"/></h1>
<h:dataTable value="#{articleBean.afficherArticles()}" var="item">
<h:column>
<f:facet name="header">
<h:outputText value="Id"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Libelle"/>
</f:facet>
<h:outputText value="#{item.libelle}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Prix"/>
</f:facet>
<h:outputText value="#{item.prix}"/>
</h:column>
</h:dataTable>
</h:form>
</f:view>
</ui:define>

Exécution

Il ne reste plus maintenant que passer à l’exécution. On fait bouton droit sur le nom de la page “Home.xhtml” et on choisit d’exécuter le fichier, ce qui donnera lieu à l’affichage de cette page comme suit : 
Template Home
Chargement de la Template principale



Nous appuyons sur le lien “Gestion Articles“ pour passer à l’affichage suivant :
Gestion des articles
Gestion des articles


C’est ainsi que nous arrivons à la fin de cet atelier, si jamais vous avez trouvé des problèmes ou vous avez des questions n’hésitez pas à les poster en commentaire.

Commentaires

Posts les plus consultés de ce blog

Rédaction d'un document Cahier des Charges

Comment rédiger un Cahier des Charges Pour rédiger un document cahier des charges d'un projet logiciel ou autre, nous proposons cette template qui pourrait servir éventuellement comme guide. Il s'agit de définir successivement les points suivants : Contexte et définition du projet, Objectifs, Scope, Parties Prenantes, Description des besoins à répartir entre les besoins fonctionnels et non fonctionnels. Contexte et définition du problème Dans cette rubrique, vous allez définir le problème pour bien clarifier la finalité du travail.  Il est important de souligner aussi les besoins ainsi que les contraintes et ce de manière  très sommaire. Par exemple, vous pouvez exposer la situation actuelle ou futur de votre système tout en mettant l’accent sur les problèmes auxquels vous voulez faire face. Objectifs Après avoir exposé le problème dans la première partie, ici vous allez exprimer quelles sont les attentes et les résultats escomptés. Normalement ces att

Scope d'un projet

Comment définir le Scope d'un projet Le Scope ou Périmètre d'un projet est un point clé pour la réussite du dit projet. Il doit figurer parmi les éléments d'un document cahier des charges et partagé avec le Manager du projet, le Client ainsi que les parties prenantes. Pour bien définir le Scope d’un projet, il est opportun de définir les points suivants : Les objectifs du projet Les buts ou finalités (goals) à atteindre Les sous-phases ou étapes Les tâches Les ressources Le budget La planning Bien sûr pour pouvoir ce faire, il est nécessaire d'élaborer une étude approfondie de la finalité du projet en concertation avec d’une part le client et d’autre part avec les parties-prenantes. Une fois ces points sont détaillés, il y a lieu après de clarifier les limitations du projet à savoir les points à inclure dans le projet et ceux à ne pas inclure. Il est à rappeler également que les objectifs du projet doivent respecter les critères SMART .

Les Tests d'Acceptation sous Fitnesse

Introduction Fitnesse est un outil de test d’acceptation automatisé pour réparer les problèmes liés aux processus d’exigences très tôt. Les tests d’acceptation automatisés de Fitnesse présentent plusieurs avantages tels que : Avoir un retour très tôt sur chaque item du projet. Avoir un retour très fréquent sur chaque item du projet. Ces tests sont déterministes dans la mesure où ils sont soient verts soient rouges. Permettent d’emprunter de plus en plus de chemins par rapport à la logique métier. A l’inverse des tests unitaires tels que jUnit ou autres, les tests d’acceptation sous Fitnesse permettent de tester le métier et se concentrent beaucoup plus pour découler sur le bon code (the right code), le code ayant le plus de valeur métier. Atelier Dans cet atelier, nous allons mettre en pratique un projet de test d’acceptation sous Fitnesse. Pour ce faire, nous allons utiliser l’IDE Eclipse avec Maven. Nous commençons par créer un projet Maven sous Eclipse