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 |
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 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 :
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 :
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 :
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” :
<!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” :
Création de la template Client |
On appuie sur Next et on saisie le nom de la page “AjouterArticle”:
La page ajouterArticle.xhtml |
Il reste à définir la template, pour cela on clique sur le bouton ‘Browse…’ en face de ‘Template’ :
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"
<!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>
<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 |
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 |
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” :
La ressource JDBC |
Nous sélectionnons après le nom du pool de connexion “gcom” créée précédemment :
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 |
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 |
Après on valide en cliquant sur “Next” pour avoir la fenêtre suivante :
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 + " ]";
}
}
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 session Bean |
On clique sur Next et on choisit la classe entite “Article” ensuite on appuie sur le bouton “Add >” pour l’ajouter :
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 |
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” :
Création de la ManagedBean |
On donne un nom à la classe, par exemple “ArticleBean” et on choisit le package “org.cours.beans” comme suit :
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;
}
}
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>
<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 :Chargement de la Template principale |
Nous appuyons sur le lien “Gestion Articles“ pour passer à l’affichage suivant :
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
Enregistrer un commentaire