premiers pas j2ee - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme...

32
Intergiciel et Construction d’Applications R´ eparties c 2007, C´ edric JOFFROY, S´ ebastien MOSSER, Michel RIVEILL (version du 14 novembre 2008 - 11:13) Chapitre9 Premiers pas J2EE L’objectif de cette annexe est de permettre ` a chacun de se familiariser un peu avec une plate-forme respectant les sp´ ecifications J2EE (Java 2 Enterprise Edition). Pour cela nous allons d´ evelopper une petite application permettant ` a chacun de g´ er´ e ses cartes de visite (ajout, suppression et consultation) et de les rendre accessibles aux autres utilisateurs (uni- quement consultation). Pour atteindre ce but, l’application se compose de deux parties : le service d’annuaire qui doit pouvoir ˆ etre utilis´ ee ` a distance et diff´ erentes applications clientes de type client l´ eger ou client lourd graphique ou en ligne de commande. Pour des raisons de simplicit´ e nous ne nous int´ eresserons pas aux probl` emes li´ es ` a l’authentification des diff´ erentes classes d’utilisateurs. Pour mettre en œuvrecette application nous allons utiliser : – un container managed entity bean pour g´ erer la persistance des cartes de visites, – un statefull session bean pour l’ajout et la suppression des cartes de visites, – un stateless session bean pour la consultation des cartes stock´ ees, – un client lourd pour administrer l’application et permettre l’ajout et la suppression de cartes de visites – un client l´ eger de consultation en utilisant une (servlet ). Une version html de ce texte est disponible ` a l’adresse http://rangiroa.polytech. unice.fr/riveill/enseignement/tp/j2ee.html. Elle contiendra les ´ evolutions futures du sujet. 9.1 Les outils ` a utiliser Parmis toutes les plates-formes J2EE disponible, nous avons fait le choix d’utiliser J2EE Jonas evelopp´ e par des ´ equipes fran¸ caises dans le cadre du consortium Object- Web qui peut ˆ etre r´ ecup´ er´ e sur le site web du consortium 1 . 1 www.objectweb.com

Upload: phungcong

Post on 15-Sep-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

Intergiciel et Construction d’Applications Repartiesc©2007, Cedric JOFFROY, Sebastien MOSSER, Michel RIVEILL

(version du 14 novembre 2008 - 11:13)

Chapitre9

Premiers pas J2EE

L’objectif de cette annexe est de permettre a chacun de se familiariser un peu avec uneplate-forme respectant les specifications J2EE (Java 2 Enterprise Edition). Pour cela nousallons developper une petite application permettant a chacun de gere ses cartes de visite(ajout, suppression et consultation) et de les rendre accessibles aux autres utilisateurs (uni-quement consultation). Pour atteindre ce but, l’application se compose de deux parties :le service d’annuaire qui doit pouvoir etre utilisee a distance et differentes applicationsclientes de type client leger ou client lourd graphique ou en ligne de commande. Pour desraisons de simplicite nous ne nous interesserons pas aux problemes lies a l’authentificationdes differentes classes d’utilisateurs.

Pour mettre en œuvrecette application nous allons utiliser :– un container managed entity bean pour gerer la persistance des cartes de visites,– un statefull session bean pour l’ajout et la suppression des cartes de visites,– un stateless session bean pour la consultation des cartes stockees,– un client lourd pour administrer l’application et permettre l’ajout et la suppression

de cartes de visites– un client leger de consultation en utilisant une (servlet).Une version html de ce texte est disponible a l’adresse http://rangiroa.polytech.

unice.fr/riveill/enseignement/tp/j2ee.html. Elle contiendra les evolutions futuresdu sujet.

9.1 Les outils a utiliser

Parmis toutes les plates-formes J2EE disponible, nous avons fait le choix d’utiliserJ2EE Jonas developpe par des equipes francaises dans le cadre du consortium Object-Web qui peut etre recupere sur le site web du consortium1.

1www.objectweb.com

Page 2: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

2 CHAPITRE 9. PREMIERS PAS J2EE

9.1.1 Installation de Jonas

L’installation proposee ici concerne la version 4.7.7 et s’adresse aux utilisation d’unemachine de type Linux ou Mac Os X. On laisse au lecteur attentif la modification decette procedure pour installer Jonas sur une plateforme Windows ou pour installer uneautre version de Jonas.

Nous allons installer Jonas dans le repertoire /opt/.

LINUX:~> tar xvfz jonas4 .7.7- tomcat5 .5.15. tgz

LINUX:~> sudo mv JONAS_4_7_7 /opt/.

Pour fonctionner correctement, Jonas utiliser trois variables d’environnement quidoivent etre correctement positionnee :

– JONAS ROOT : chemin d’acces au repertoire de Jonas,– PATH : chemin d’acces aux binaires de Jonas,– CLASSPATH : doit contenir les deux archives necessaire au bon deroulement de ces

ateliers : ejb-2 1-api.jar et servlet-2 4.jar.– selon les versions Jonas, il peut y avoir d’autres variables d’environneent : SPS=’ :’

et JONAS BASE=JONAS ROOT

9.1.2 Installation d’ANT

L’installation Ant est recommandee si l’on veut tester les exemples fournis avec Jonaset qui se trouve dans le repertoire /opt/JONAS 4 7 7/examples/src/. Ant est par exempledisponible a l’url http://ant.apache.org/bindownload.cgi et s’installe tres aisement.

LINUX:~> unzip apache -ant -1.6.5 - bin.zip

LINUX:~> sudo mv apache -ant -1.6.5 /opt/.

Comme pour Jonas, il est necessaire que la variable d’environnement ANT HOME

contienne le repertoire d’installation de Ant.

9.1.3 Mise a jour des variables d’environnement

Pour etre certain de ne pas oublier une mise a jour lors d’une utilisation ulterieure,nous vous invitons a regrouper celles-ci dans le fichier environnement.sh.

#!/bin/sh

# Mise a jour des variables d’environnemnts pour Jonas

JONAS_ROOT =/opt/JONAS_4_7_7

echo "JONAS_ROOT set to $JONAS_ROOT"

PATH=$JONAS_ROOT/bin/unix:$PATH

echo "PATH set to $PATH"

CLASSPATH=$CLASSPATH:$JONAS_ROOT/lib/commons/j2ee/ejb -2_1 -api.jar

CLASSPATH=$CLASSPATH:$JONAS_ROOT/lib/commons/j2ee/servlet -2_4.jar

echo "CLASSPATH set to $CLASSPATH"

# Mise a jour des variables d’environnement pour Ant

Page 3: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.2. GESTION DE LA PERSISTANCE - ENTITY BEAN 3

ANT_HOME =/opt/apache -ant -1.6.5

echo "ANT_HOME set to $ANT_HOME"

export JONAS_ROOT ANT_HOME PATH CLASSPATH

Listing 9.1 – Fichier environment.sh

Il ne reste plus qu’a executer ce shell a l’aide de la commande source pour s’affranchirdu dialecte utilise (zsh, tcsh ou bash) :

LINUX:~> source environnement.sh

9.1.4 Pour tester l’installation

Avant toutes autres manipulation, un test de l’installation s’impose. Suivez attentive-ment les differents messages d’erreurs.

LINUX:~> jonas check

LINUX:~> jonas start

1. Le check verifie l’etat de l’installation, et peut renvoyer des warnings, rien de biengrave.

2. Le start lance le serveur Jonas. Lorsque le lancement est termine, il rend la mainen indiquant qu’il a demarre.

9.2 Gestion de la persistance - entity bean

Les objets persistants sont les cartes de visites. Nous allons donc les implementer sousla forme d’entity bean dont la persistance est directement geree par le container. Avantd’ecrire l’entity bean, construisons la base de donnees.

9.2.1 La base de donnees

Pour conserver les cartes de visite nous allons utiliser une base de donnee qui contiendraune seule table CARTEDEVISITE structuree de la maniere suivante :

– un id permettant d’identifier de maniere unique chacune des cartes de visite,– un nom,– un prenom,– une adresse mail,– un numero de telephone.Tous ces champs sont de type varchar et sont non nuls, a l’exception du champ id qui

est de type identity (shortcut pour un integer primary key dans le SGBD utilise).Nous utiliserons le micro–moteur de base de donnees HSQLDB, livre avec Jonas. Les

informations de connexion sont les suivantes

urlid localhost -dbjonas

url jdbc:hsqldb:hsql :// localhost :9001/ db_jonas

username jonas

Page 4: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

4 CHAPITRE 9. PREMIERS PAS J2EE

password jonas

Listing 9.2 – Fichier sql-rc.conf

Description du schema relationnel

1 drop table if exists CARTEDEVISITE;

create table CARTEDEVISITE (

ID IDENTITY ,

NOM varchar (255) not null ,

PRENOM varchar (255) not null ,

6 EMAIL varchar (255) not null ,

PHONE varchar (255) not null

);

Listing 9.3 – Fichier database.sql

Chargement de la relation dans le moteur

LINUX:~> java -jar $JONAS_ROOT/lib/commons/jonas/hsqldb.jar \

2 --autoCommit --continueOnErr \

--rcfile ./sql -rc.conf localhost -dbjonas database.sql

Script de chargement automatique

Pour simplifier l’initialisation de la base de donnees, on met en place un script quipermet d’executer cette ligne de commande :

#!/bin/sh

2 echo "Database initialization"

java -jar $JONAS_ROOT/lib/commons/jonas/hsqldb.jar \

--autoCommit --continueOnErr \

--rcfile ./sql -rc.conf localhost -dbjonas database.sql

Listing 9.4 – Fichier initDatabase.sh

Pour executer ce script (apres l’avoir rendu executable . . .) :

LINUX:~> ./ initDatabase.sh

On dispose maintenant d’une relation vide dans le moteur de base de donnees HSQL.Si vous n’etes pas convaincu, lancez le client graphique Hsql Manager sans toucher aumot de passe :

LINUX:~> java -cp $JONAS_ROOT/lib/commons/jonas/hsqldb.jar org.hsqldb.util.DatabaseManager

Page 5: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.2. GESTION DE LA PERSISTANCE - ENTITY BEAN 5

9.2.2 Ecriture du container managed entity bean

Le code d’un entity bean est reparti dans plusieurs classes Java et descripteurs :– Remote Interface : l’interface qui definit les differentes methodes du Bean qui seront

accessibles pour les clients,– Home Interface : l’interface qui est visible par le client pour creer, retrouver puis

manipuler des instances du Bean,– la classe d’implementation du Bean,– deux descripteurs de deploiement indiquant entre autre le mapping objet ⇔

relationnel a utiliser pour garantir la persistance des objets, et les requetes per-mettant de les retrouver.

Interface remote : on decrit dans cette interface les fonctions permettant de manipulerles cartes de visite.

package carte_cmp;

import javax.ejb.EJBObject;

4 import java.rmi.RemoteException;

public interface CarteDeVisiteCMP extends EJBObject {

public Integer getId () throws RemoteException;

9 public String getNom () throws RemoteException;

public String getPrenom () throws RemoteException;

public String getEmail () throws RemoteException;

public String getPhone () throws RemoteException;

14 // Pas de setId , le SGBD la genere.

public void setPrenom(String prenom) throws RemoteException;

public void setNom(String nom) throws RemoteException;

public void setEmail(String email) throws RemoteException;

public void setPhone(String phone) throws RemoteException;

19 }

Listing 9.5 – Fichier CarteDeVisiteCMP.java

Interface Home : cette interface, accessible par les clients de l’application, permetde retouver les instances de cartes de visites, d’en creer, . . .. Les instances qu’elle renvoiesont du type de l’interface precedente, ce qui masque aux clients l’implementation reelledu Bean.

1 package carte_cmp;

import java.rmi.RemoteException;

import javax.ejb .*;

import java.util .*;

6

public interface CarteDeVisiteCMPHome extends EJBHome {

public CarteDeVisiteCMP

create(String nom , String prenom , String email , String phone)

Page 6: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

6 CHAPITRE 9. PREMIERS PAS J2EE

11 throws RemoteException , CreateException;

public CarteDeVisiteCMP findByPrimaryKey(Integer id)

throws RemoteException , FinderException;

16 public Collection findByNom(String nom)

throws RemoteException , FinderException;

public Collection findByPrefix(String prefix)

throws RemoteException , FinderException;

21 }

Listing 9.6 – Fichier CarteDeVisiteCMPHome.java

Implementation du bean Le choix d’utiliser un CMP entity bean simplifie grandementla mise en oeuvre puis que la plupart des methodes n’ont pas besoin d’etre implementeeset seront generees a partir des fichiers de deploiement.

package carte_cmp;

import java.sql .*;

4 import javax.sql .*;

import java.util .*;

import javax.ejb .*;

import javax.naming .*;

9 public abstract class CarteDeVisiteCMPBean implements EntityBean {

/** Abstract ==> gere par le conteneur **/

public abstract Integer getId ();

public abstract void setId(Integer id);

14 public abstract String getNom ();

public abstract void setNom(String nom);

public abstract String getPrenom ();

public abstract void setPrenom(String prenom );

public abstract String getEmail ();

19 public abstract void setEmail(String email );

public abstract String getPhone ();

public abstract void setPhone(String phone );

// Cree le composant et le sauvegarde dans la base de donnees avec

24 // un insert

public Integer

ejbCreate(String nom , String prenom , String email , String phone)

throws CreateException {

// renseigne les propriete du composant

29 setNom(nom);

setPrenom(prenom );

setEmail(email );

setPhone(phone );

return null;

34 }

public void

ejbPostCreate(String nom , String prenom ,

Page 7: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.2. GESTION DE LA PERSISTANCE - ENTITY BEAN 7

String email , String phone) {

39 // Dans le cas de tables de liaisons , on instancierait les

// liaisons ici.

}

// les methodes suivantes n’ont pas besoin d etre implemante dans

44 // le cadre d un CMP entity bean

public void ejbRemove () throws RemoveException { }

public void setEntityContext(EntityContext context) {

this.context = context;

}

49 public void unsetEntityContext () { this.context = null; }

public void ejbActivate () { }

public void ejbPassivate () { }

public void ejbLoad () { }

54 public void ejbStore () { }

}

Listing 9.7 – Fichier CarteDeVisiteCMPBean.java

La cle primaire utilisee sera de type auto incrementee (par la base de donnee). Nousn’utiliserons donc jamais la methode setId().

TODO pourquoi alors mettre cette methode ? on a besoin de l’operation ’setId’ car legenerateur de code rale si elle n’y est pas. Reste a le reverifier.

Descripteur de deploiement J2EE : ce fichier est commun a tous les serveur d’ap-plications J2ee et permet de preciser le mapping a utiliser entre l’entity bean et la basede donnee.

<?xml version ="1.0" encoding ="ISO -8859 -1"? >

<ejb -jar >

<description >Descripteur de deploiement pour l EJB carte de visite

</description >

5 <display -name >EJB CarteDeVisite </display -name >

<enterprise -beans >

<entity >

<description >EJB CarteDeVisite ( CMP )</description >

<ejb -name >CarteDeVisiteCMP </ejb -name >

10 <home >carte_cmp.CarteDeVisiteCMPHome </home >

<remote >carte_cmp.CarteDeVisiteCMP </remote >

<ejb -class >carte_cmp.CarteDeVisiteCMPBean </ejb -class >

<persistence -type >Container </ persistence -type >

<prim -key -class >java.lang.Integer </prim -key -class >

15 <reentrant >False </reentrant >

<abstract -schema -name >cartedevisite </abstract -schema -name >

<cmp -field >

<field -name >id </field -name >

</cmp -field >

20 <cmp -field >

<field -name >nom </field -name >

</cmp -field >

<cmp -field >

<field -name >prenom </field -name >

25 </cmp -field >

Page 8: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

8 CHAPITRE 9. PREMIERS PAS J2EE

<cmp -field >

<field -name >email </field -name >

</cmp -field >

<cmp -field >

30 <field -name >phone </field -name >

</cmp -field >

<primkey -field >id </primkey -field >

<query >

<query -method >

35 <method -name >findByNom </method -name >

<method -params >

<method -param >java.lang.String </method -param >

</method -params >

</query -method >

40 <ejb -ql >SELECT OBJECT(o) FROM cartedevisite o

WHERE o.nom = ?1

</ejb -ql >

</query >

<query >

45 <query -method >

<method -name >findByPrefix </method -name >

<method -params >

<method -param >java.lang.String </method -param >

</method -params >

50 </query -method >

<ejb -ql >SELECT OBJECT(o) FROM cartedevisite o

WHERE LOCATE (?1,o.nom) > 0

</ejb -ql >

</query >

55 <query >

<query -method >

<method -name >findByPrimaryKey </method -name >

<method -params >

<method -param >java.lang.Integer </method -param >

60 </method -params >

</query -method >

<ejb -ql >SELECT OBJECT(o) FROM cartedevisite o

WHERE o.id = ?1

</ejb -ql >

65 </query >

</entity >

</enterprise -beans >

<assembly -descriptor >

70 <container -transaction >

<method >

<ejb -name >CarteDeVisiteCMP </ejb -name >

<method -name >*</method -name >

</method >

75 <trans -attribute >Required </trans -attribute >

</container -transaction >

</assembly -descriptor >

</ejb -jar >

Listing 9.8 – Fichier ejb-jar.xml

Page 9: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.2. GESTION DE LA PERSISTANCE - ENTITY BEAN 9

Descripteur Jonas : En complement du descripteur J2EE, chaque fournisseur de plate-forme propose son propre descripteur afin de completer la description initiale. Dans Jonas,il permet de decrire l’utilisation des ressources tierces comme par exemple l’acces a la basede donnees.

1 <?xml version ="1.0" encoding ="ISO -8859 -1"? >

<jonas -ejb -jar >

<jonas -entity >

<ejb -name >CarteDeVisiteCMP </ejb -name >

<jndi -name >MyCarteDeVisiteCMP </jndi -name >

6 <jdbc -mapping >

<jndi -name >jdbc_1 </jndi -name >

<jdbc -table -name >CARTEDEVISITE </jdbc -table -name >

<automatic -pk>true </automatic -pk>

<cmp -field -jdbc -mapping >

11 <field -name >id </field -name >

<jdbc -field -name >ID </jdbc -field -name >

</cmp -field -jdbc -mapping >

<cmp -field -jdbc -mapping >

<field -name >nom </field -name >

16 <jdbc -field -name >NOM </jdbc -field -name >

</cmp -field -jdbc -mapping >

<cmp -field -jdbc -mapping >

<field -name >prenom </field -name >

<jdbc -field -name >PRENOM </jdbc -field -name >

21 </cmp -field -jdbc -mapping >

<cmp -field -jdbc -mapping >

<field -name >phone </field -name >

<jdbc -field -name >PHONE </jdbc -field -name >

</cmp -field -jdbc -mapping >

26 <cmp -field -jdbc -mapping >

<field -name >email </field -name >

<jdbc -field -name >EMAIL </jdbc -field -name >

</cmp -field -jdbc -mapping >

</jdbc -mapping >

31 </jonas -entity >

</jonas -ejb -jar >

Listing 9.9 – Fichier jonas-ejb-jar.xml

9.2.3 Compilation et deploiement de l’entity bean

Nous avons maintenant tout ce qui est necessaire pour compiler et deployer l’entitybean. A l’issue de cette premiere etape nous avons l’arborescence suivante :

+--> bin/

+--> META -INF/

3 +--> ejb -jar.xml

+--> jonas -ejb -jar.xml

+--> src/

+--> CarteDeVisiteCMPBean.java

+--> CarteDeVisiteCMPHome.java

8 +--> CarteDeVisiteCMP.java

+--> Test.java

Page 10: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

10 CHAPITRE 9. PREMIERS PAS J2EE

Nous conserverons cette arborescence pour les autres beans que nous creerons. Lerepertoire bean contiendra toujours le code compile des fichiers java et le repertoirebin/META-INF, les descripteurs.

Pour pouvoir etre execute par Jonas, un bean a besoin d’etre contenu dans une archivequi facilite son deploiement. Pour cela, on genere le bytecode, puis on ecrit les descripteurde deploiement et on archive l’ensemble dans un fichier jar.

1 LINUX :~/ CarteDeVisite > javac -d bin src/*. java

LINUX :~/ CarteDeVisite > cp *.xml bin/META -INF/.

LINUX :~/ CarteDeVisite > cd bin

LINUX :~/ CarteDeVisite/bin > jar cf ../ CarteDeVisiteCMP.jar

LINUX :~/ CarteDeVisite/bin > cd ..

6 LINUX :~/ CarteDeVisite >

Deployer un bean dans Jonas se fait en deux etapes :– deposer l’archive dans le repertoire ejbjars de Jonas,– utiliser l’outils d’administration de Jonas pour publier le bean.

LINUX :~/ CarteDeVisite > cp CarteDeVisiteCMP.jar $JONAS_ROOT/ejbjars /.

LINUX :~/ CarteDeVisite > cd $JONAS_ROOT/ejbjars

LINUX:/opt/JONAS_4_7_7/ejbjars > jonas admin -a CarteDeVisiteCMP.jar

4 LINUX:/opt/JONAS_4_7_7/ejbjars > cd -

LINUX :~/ CarteDeVisite >

9.2.4 Client d’un entity bean

Ce client, non essentiel a l’application, permet de valider le code de l’entity bean. Nousfaisons le choix d’implementer un client simple qui cree deux entity bean, effectue unerecherche par nom et une recherche a l’aide d’un prefixe.

package carte_cmp;

import java.util.Properties;

import javax.naming.InitialContext;

5 import javax.naming.Context;

import javax.rmi.PortableRemoteObject;

import java.util.Collection;

import java.util.Iterator;

10

public class Test {

public static void main(String args []) {

15 try {

// Recherche de l’interface home de l’EJB

Context initialContext = new InitialContext ();

Object objref = initialContext.lookup("MyCarteDeVisiteCMP");

20

// Reference a l’interface locale de l’EJB

CarteDeVisiteCMPHome home = (CarteDeVisiteCMPHome)

PortableRemoteObject.narrow(objref , CarteDeVisiteCMPHome.class );

Page 11: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.2. GESTION DE LA PERSISTANCE - ENTITY BEAN 11

25 // Creation deux carte de visite dans la base de donnees

CarteDeVisiteCMP toto =

home.create("TOTO", "toto", "toto@toto", "0123456");

CarteDeVisiteCMP titi =

home.create("TITI", "titi", "titi@titi", "9876443");

30

// Objet de type client pour faire nos tests

CarteDeVisiteCMP test;

35 // Recherche par le nom de la personne

System.out.println("Liste des clients qui ont pour nom TOTO :");

Collection cl = home.findByNom("TOTO");

Iterator iLast = cl.iterator ();

while (iLast.hasNext ()) {

40 test = iLast.next ();

System.out.println("->" + test.getPrenom ());

}

// Recherche par le prefixe de la personne

45 System.out.println("Liste des clients qui ont pour prefixe T :");

Collection c2 = home.findByPrefix("T");

Iterator iLast1 = c2.iterator ();

while (iLast1.hasNext ()) {

test = iLast1.next ();

50 System.out.println("->" + test.getPrenom ());

}

} catch (Exception e) {

System.err.println("Erreur : " + e);

55 System.exit (2);

}

}

}

Listing 9.10 – Fichier Test.java

9.2.5 Compilation et execution du client

Apres avoir compile le client, nous utilisons pour l’executer, l’utilitaire jclient quipermet l’execution du client dans le contexte de Jonas et d’avoir ainsi l’acces a l’annuairede referencement JNDI dans lequel sont enregistres tous les beans publies dans Jonas.

Nous considererons que le client possede dans son CLASSPATH le jar du bean, pour pou-voir utiliser le proxy (classe RemoteStub generee par genic) permettant d’acceder au beancomme un objet distant. Pour ’travailler proprement’, il serait beaucoup plus judicieux dedonner au client soit le proxy, soit une maniere de le generer.

1 LINUX :~/ CarteDeVisite > jclient \

-cp $JONAS_ROOT/ejbjars/CarteDeVisiteCMP.jar \

-argclient carte_cmp.Test

ClientContainer.info : Starting client ...

Liste des clients qui ont pour nom TOTO :

6 -> toto

Page 12: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

12 CHAPITRE 9. PREMIERS PAS J2EE

Liste des clients qui ont pour prefixe T :

-> toto

-> titi

9.2.6 Automatisation des taches repetitives

La compilation, le deployement et la publication d’un bean, ainsi que la compilationet l’execution d’un client sont des taches repetitives qu’il est aise d’automatiser. Voici unexemple de script bash qui rendra la suite de l’ennonce beaucoup plus lisible. Ce scriptpermet :

– de compiler et generer l’archive d’un bean (compile),– de le deployer et de le publier (load),– de compiler et d’executer un client (run),– de retirer le bean publie (unload),– et de nettoyer les sources (clean).TODO valider le script pour tcsh

1 #!/bin/sh

# ATTENTION : fonctionne en bash , zsh

JAR_NAME=CarteDeVisiteCMP.jar

6 CLIENT_CLASS_NAME=carte_cmp.Test

### DO NOT EDIT AFTER THIS LINE !! ###

export JAR_NAME CLIENT_CLASS_NAME

11 function compile () {

echo "## src --> bin compilation "

javac -d bin src/*. java

echo "## Deploying xml descriptors"

cp *.xml bin/META -INF/.

16 echo "## Building $JAR_NAME"

cd bin

jar cf ../ $JAR_NAME *

cd ..

}

21

function load() {

echo "## Moving $JAR_NAME --> $JONAS_ROOT/ejbjars"

mv $JAR_NAME $JONAS_ROOT/ejbjars /.

echo "## Loading $JAR_NAME in JONAS"

26 cd $JONAS_ROOT/ejbjars

jonas admin -a $JAR_NAME

cd -

}

31 function unload () {

echo "## Unloading $JAR_NAME from JONAS"

cd $JONAS_ROOT/ejbjars

jonas admin -r $JAR_NAME

cd -

36 }

Page 13: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.2. GESTION DE LA PERSISTANCE - ENTITY BEAN 13

function run() {

echo "## Runnning client ... "

jclient -cp $JONAS_ROOT/ejbjars/$JAR_NAME -argclient $CLIENT_CLASS_NAME

41 }

function clean () {

echo "## Cleaning directories"

rm -rf *~ *.jar src /*~ bin/*

46 mkdir bin/META -INF

}

function main() {

case $1 in

51 "compile") compile ;;

"load") load;;

"unload") unload ;;

"run") run;;

"clean") clean;;

56 "all") unloand; clean; compile; load; run;;

*) "Unknown Command : [$1]";;

esac

}

61 main $@

Listing 9.11 – Fichier manage.sh

La gestion d’un bean devient simple. Il suffit de modifier l’entete pour indique le nomdu bean et le nom du client et d’executer ce script en precisant l’action a effectuer.

LINUX :~/ CarteDeVisite > ./ manage.sh clean

## Cleaning directories

LINUX :~/ CarteDeVisite > ./ manage.sh compile

4 ## src --> bin compilation

## Deploying xml descriptors

## Building CarteDeVisiteCMP.jar

LINUX :~/ CarteDeVisite > ./ manage.sh load

## Moving CarteDeVisiteCMP.jar --> /opt/JONAS_4_7_7/ejbjars

9 ## Loading CarteDeVisiteCMP.jar in JONAS

LINUX :~/ CarteDeVisite > ./ manage.sh run

## Runnning client ...

ClientContainer.info : Starting client ...

Liste des clients qui ont pour nom TOTO :

14 ->toto

->toto

Liste des clients qui ont pour prefixe T :

->toto

->titi

19 ->toto

->titi

LINUX :~/ CarteDeVisite > ./ manage.sh unload

## Unloading CarteDeVisiteCMP.jar from JONAS

Note : Nous utiliserons systematiquement ce script par la suite.

Page 14: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

14 CHAPITRE 9. PREMIERS PAS J2EE

9.3 La partie metier - statefull session bean

9.3.1 Principe

Dans le cadre d’une architecture n− tiers, il n’est pas pensable d’offrir aux differentsclients la possibilite de manipuler directement les entity beans qui representent des donneesdans la base de donnees. En effet, les acces sont trop elementaires. Nous allons encapsulerla logique metier de l’application dans un session bean.

Les operations d’ajout et de supression de cartes etant critiques nous allons unique-ment les autoriser pour l’administrateur de l’application a l’aide d’un bean de session aetat (statefull session bean), dans lequel on positionnera un etat estIdentifie. L’executiondes actions d’ajout et de suppression sera autorisee uniquement pour les utilisateurs au-thentifies.

9.3.2 Ecriture du statefull session bean

Comme pour un entity bean, l’ecriture d’un session bean demande l’ecriture de deuxinterfaces (l’interface remote et l’interface home), d’une classe java implementant le beanet de deux descripteurs de configuration (celui present dans toutes plates-formes J2EE etcelui de Jonas).

Interface remote

package administrators;

3 import javax.ejb.EJBObject;

import java.rmi.RemoteException;

public interface Administrator extends EJBObject {

// Log into the bean

8 public boolean login(String username , String password)

throws RemoteException;

// Log out from the bean

public boolean logout () throws RemoteException;

13

// Add a ’CarteDeVisite ’ inside the system

public boolean add (String nom , String prenom ,

String mail , String phone)

throws RemoteException;

18

// Delete a card , using the id to retrieve the good one

public boolean delete (int id) throws RemoteException;

}

Listing 9.12 – Fichier Administrator.java

Interface home

Page 15: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.3. LA PARTIE METIER - STATEFULL SESSION BEAN 15

package administrators;

3 import java.rmi.RemoteException;

import javax.ejb.CreateException;

import javax.ejb.EJBHome;

public interface AdministratorHome extends EJBHome {

8 // Constructeur par defaut

Administrator create () throws RemoteException , CreateException;

// Permet de se logger directement a la creation

Administrator create(String username , String password)

13 throws RemoteException , CreateException;

}

Listing 9.13 – Fichier AdministratorHome.java

Implementation du session bean

package administrators;

import java.rmi.RemoteException;

import javax.ejb.SessionBean;

5 import javax.ejb.SessionContext;

import javax.rmi .*;

import javax.naming.InitialContext;

import javax.naming.Context;

10

import java.util .*;

import carte_cmp .*;

15 public class AdministratorBean implements SessionBean {

private boolean isLogged;

public boolean login(String username , String password) {

20 if (username.equals("admin") && password.equals("admin")) {

this.isLogged = true;

return true;

}

return false;

25 }

public boolean logout () {

this.isLogged = false;

return true;

30 }

public boolean add (String nom , String prenom , String mail , String phone) {

try {

if (isLogged) {

Page 16: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

16 CHAPITRE 9. PREMIERS PAS J2EE

35 Context initialContext = new InitialContext ();

Object objref = initialContext.lookup("MyCarteDeVisiteCMP");

// Reference a l’interface locale de l’EJB

CarteDeVisiteCMPHome home = (CarteDeVisiteCMPHome)

40 PortableRemoteObject.narrow(objref ,

CarteDeVisiteCMPHome.class );

// Objet de type CarteDeVisite , avec creation de cet objet

CarteDeVisiteCMP test = home.create (nom , prenom , mail , phone );

45

return true;

} else return false;

}

catch (Exception e) {

50 System.err.println("Erreur : " + e);

}

return false;

}

55 public boolean delete (int id) {

try {

if (isLogged) {

Context initialContext = new InitialContext ();

Object objref = initialContext.lookup("MyCarteDeVisiteCMP");

60

// Reference a l’interface locale de l’EJB

CarteDeVisiteCMPHome home = (CarteDeVisiteCMPHome)

PortableRemoteObject.narrow(objref ,

CarteDeVisiteCMPHome.class );

65

// Objet de type CarteDeVisite , en vue de le supprimer

// de la table

CarteDeVisiteCMP test = home.findByPrimaryKey(id);

if (test != null){

70 test.remove ();

return true;

} else return false;

} else return false;

}

75 catch (Exception e) {

System.err.println("Erreur : " + e);

}

return false;

}

80

public void ejbCreate () { this.isLogin = false; }

public void ejbCreate(String username , String password) {

if (username.equals("admin") && password.equals("admin"))

85 this.isLogin = true;

else

this.isLogin = false;

}

90 public void ejbRemove () {}

Page 17: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.3. LA PARTIE METIER - STATEFULL SESSION BEAN 17

public void ejbActivate () {}

public void ejbPassivate () {}

public void setSessionContext(SessionContext sc) {}

95 }

Listing 9.14 – Fichier AdministratorBean.java

Descripteur J2EE

<?xml version ="1.0" encoding ="ISO -8859 -1"? >

<ejb -jar >

<description >Descripteur de deploiement du bean administratif

</description >

5 <display -name >Administrator </display -name >

<enterprise -beans >

<session >

<description >Administrator </ description >

<display -name >Administrator </display -name >

10 <ejb -name >Administrator </ejb -name >

<home >administrators.AdministratorHome </home >

<remote >administrators.Administrator </remote >

<ejb -class >administrators.AdministratorBean </ejb -class >

<session -type >Stateful </session -type >

15 <transaction -type >Container </ transaction -type >

</session >

</enterprise -beans >

<assembly -descriptor >

<container -transaction >

20 <method >

<ejb -name >Administrator </ejb -name >

<method -name >*</method -name >

</method >

<trans -attribute >Required </trans -attribute >

25 </container -transaction >

</assembly -descriptor >

</ejb -jar >

Listing 9.15 – Fichier ejb-jar.xml

Descripteur Jonas

<?xml version ="1.0" encoding ="ISO -8859 -1"? >

<jonas -ejb -jar >

3 <jonas -session >

<ejb -name >Administrator </ejb -name >

<jndi -name >MyAdministrator </jndi -name >

</jonas -session >

</jonas -ejb -jar >

Listing 9.16 – Fichier jonas-ejb-jar.xml

Page 18: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

18 CHAPITRE 9. PREMIERS PAS J2EE

9.3.3 Ecriture d’un client du session bean

Comme pour l’entity bean, nous allons construire un client capable de se connecter ausession bean precedemment decrit.

package administrators;

3 import java.util.Properties;

import javax.naming.InitialContext;

import javax.naming.Context;

import javax.rmi.PortableRemoteObject;

8 import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.IOException;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

13

import java.util .*;

import carte_cmp .*;

18 public class AdministratorClient {

public static void main(String args []) {

try {

23

InputStreamReader isr = new InputStreamReader ( System.in );

BufferedReader br = new BufferedReader ( isr );

boolean isQuit = false;

// Recherche de l’interface home de l’EJB

28 Context initialContext = new InitialContext ();

Object objref = initialContext.lookup("MyAdministrator");

// Reference a l’interface locale de l’EJB

AdministratorHome home = (AdministratorHome)

33 PortableRemoteObject.narrow(objref ,

AdministratorHome.class );

// Creation d’un administrateur

Administrator myAdministrator = home.create ();

38 while (isQuit == false) {

System.out.println("1. Connexion");

System.out.println("2. Quitter");

System.out.println(">");

String principalChoice = null;

43 principalChoice = br.readLine ();

if (principalChoice.equals("2")){

isQuit = true;

System.out.println("Bye bye ...");

48 }

else if (principalChoice.equals("1")){

System.out.println("Username : ");

String username = null;

Page 19: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.3. LA PARTIE METIER - STATEFULL SESSION BEAN 19

username = br.readLine ();

53

System.out.println("Password : ");

String password = null;

password = br.readLine ();

if (myAdministrator.login(username , password )){

58 boolean isLog = true;

while (isLog == true){

System.out.println("1. Ajouter une carte "

+"de visite");

System.out.println("2. Retirer une carte "

63 +"de visite");

System.out.println("3. Se deconnecter");

System.out.println(">");

String secondaryChoice = null;

secondaryChoice = br.readLine ();

68 if (secondaryChoice.equals("1")){

System.out.println("Ajout d’une "

+"carte de visite ...");

System.out.println("Entrer le nom : ");

String nom = null;

73 nom = br.readLine ();

System.out.println("Entrer le prenom : ");

String prenom = null;

prenom = br.readLine ();

System.out.println("Entrer le mail : ");

78 String mail = null;

mail = br.readLine ();

System.out.println("Entrer le numero de "

+"tel : ");

String phone = null;

83 phone = br.readLine ();

boolean isAdd = myAdministrator.add(nom ,

prenom ,

mail ,

phone );

88 if (isAdd ){

System.out.println("Ajout reussi ...");

}

else{

System.out.println("Ajout echoue ...");

93 }

}

else if (secondaryChoice.equals("2")){

System.out.println("Suppression d’une"

+" carte de visite ...");

98 System.out.println("Entrer l’ID : ");

String id = null;

id = br.readLine ();

int idToDelete = Integer.parseInt(id);

boolean isDelete =

103 myAdministrator.delete(idToDelete );

if (isDelete ){

System.out.println("Suppression "

+"reussie ...");

}

Page 20: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

20 CHAPITRE 9. PREMIERS PAS J2EE

108 else{

System.out.println("Supression "

+"echouee ...");

}

}

113 else if (secondaryChoice.equals("3")){

myAdministrator.logout ();

isLog = false;

System.out.println("Logout ...");

}

118 else{

System.out.println("Choix incorrect ...");

}

}

}

123 else{

System.out.println("Username ou Password "

+"incorrect ...");

}

}

128 else{

System.out.println("Choix incorrect ...");

}

}

} catch (Exception e) {

133 System.err.println("Erreur : " + e);

System.exit (2);

}

}

}

Listing 9.17 – Fichier AdministratorClient.java

9.3.4 Compilation du bean et du client, deploiement du bean etexecution du client

Il est essentiel que le repertoire du session bean connaisse les interfaces de l’entitybean qu’il va acceder. Il est donc necessaire de copier les interfaces home et remote del’entity bean (CarteDeVisiteCMPHome.java et CarteDeVisiteCMP.java) dans le repertoiresrc du session bean avec l’ensemble du package2.

Il reste aussi a copier le script associe a l’entity bean (manage.sh) dans le repertoiredu session bean et de le mettre a jour avec les modifications suivantes :

JAR_NAME=Administrator.jar

CLIENT_CLASS_NAME=administrators.AdministratorClient

L’execution du client doit etre parametree de la maniere suivante :

jclient -cp /opt/JONAS_4_7_7/ejbjars/$JAR_NAME :\

$JONAS_ROOT/ejbjars/CarteDeVisiteCMP.jar \

3 -argclient $CLIENT_CLASS_NAME

2Une solution plus eleguante, laisxssee au lecteur en exercice, serait d’implementer un systeme de char-gement de classe dynamique qui telechargerait ces classes depuis le serveur Jonas a l’execution.

Page 21: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.3. LA PARTIE METIER - STATEFULL SESSION BEAN 21

Il ne reste plus qu’a utiliser le script pour compiler le bean et le client, deployer le beanpuis execution le client.

LINUX :~/ Administrator > ./ manage.sh compile

2 ## src --> bin compilation

## Deploying xml descriptors

## Building Administrator.jar

LINUX :~/ Administrator >

LINUX :~/ Administrator > ./ manage.sh load

7 ## Moving Administrator.jar --> /opt/JONAS_4_7_7/ejbjars

## Loading Administrator.jar in JONAS

LINUX :~/ Administrator > ./ manage.sh run

## Runnning client ...

ClientContainer.info : Starting client ...

12 1. Connexion

2. Quitter

>

toto

Choix incorrect ...

17 1. Connexion

2. Quitter

>

1

Username :

22 toto

Password :

titi

Username ou Password incorrect ...

1. Connexion

27 2. Quitter

>

1

Username :

admin

32 Password :

admin

1. Ajouter une carte de visite

2. Retirer une carte de visite

3. Se deconnecter

37 >

1

Ajout d’une carte de visite ...

Entrer le nom :

MOSSER

42 Entrer le prenom :

sebastien

Entrer le mail :

[email protected]

Entrer le numero de tel :

47 01234566

Ajout reussi ...

1. Ajouter une carte de visite

2. Retirer une carte de visite

3. Se deconnecter

52 >

1

Page 22: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

22 CHAPITRE 9. PREMIERS PAS J2EE

Ajout d’une carte de visite ...

Entrer le nom :

JOFFROY

57 Entrer le prenom :

Cedric

Entrer le mail :

[email protected]

Entrer le numero de tel :

62 987654321

Ajout reussi ...

1. Ajouter une carte de visite

2. Retirer une carte de visite

3. Se deconnecter

67 >

3

Logout ...

1. Connexion

2. Quitter

72 >

2

Bye bye ...

9.4 La partie metier (suite) - stateless session bean

Apres avoir ecrit la partie metier qui sera utilise par l’administrateur de l’application,nous allons construire celle utilisee par tous les utilisateurs souhaitant consulter la base decartes de visite. La consultation d’une carte ne necessite pas de session, nous utiliseronsdonc un stateless session bean.

Comme tout bean, un stateless session bean a une remote interface, une home interface,une implementation et deux descripteurs.

9.4.1 Ecriture du stateless session bean

Remote interface

1 package consultators;

import javax.ejb.EJBObject;

import java.rmi.RemoteException;

6 import java.util .*;

public interface Consultator extends EJBObject {

// Find a card looking on name

11 public Collection rechercherNom(String nom)

throws RemoteException;

// Find a card with a prefix

public Collection rechercherPrefix(String prefix)

16 throws RemoteException;

}

Page 23: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.4. LA PARTIE METIER (SUITE) - STATELESS SESSION BEAN 23

Listing 9.18 – Fichier Consultator.java

Home interface

package consultators;

3 import java.rmi.RemoteException;

import javax.ejb.CreateException;

import javax.ejb.EJBHome;

public interface ConsultatorHome extends EJBHome {

8

Consultator create () throws RemoteException , CreateException;

}

Listing 9.19 – Fichier ConsultatorHome.java

Implementation du bean

package consultators;

import java.rmi.RemoteException;

4 import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

import javax.rmi .*;

import javax.naming.InitialContext;

9 import javax.naming.Context;

import java.util .*;

import carte_cmp .*;

14

public class ConsultatorBean implements SessionBean {

public Collection rechercherNom(String nom) {

try {

19 Context initialContext = new InitialContext ();

Object objref = initialContext.lookup("MyCarteDeVisiteCMP");

// Reference a l’interface locale de l’EJB

CarteDeVisiteCMPHome home = (CarteDeVisiteCMPHome)

24 PortableRemoteObject.narrow(objref ,

CarteDeVisiteCMPHome.class );

// Objet de type client pour faire nos tests

CarteDeVisiteCMP test;

29

// Recherche par le nom de la personne

Collection c1 = home.findByNom(nom);

Page 24: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

24 CHAPITRE 9. PREMIERS PAS J2EE

return c1;

34 }

catch (Exception e) {

System.err.println("Erreur : " + e);

}

return null;

39 }

public Collection rechercherPrefix(String prefix) {

try {

Context initialContext = new InitialContext ();

44 Object objref = initialContext.lookup("MyCarteDeVisiteCMP");

// Reference a l’interface locale de l’EJB

CarteDeVisiteCMPHome home = (CarteDeVisiteCMPHome)

PortableRemoteObject.narrow(objref ,

49 CarteDeVisiteCMPHome.class );

// Objet de type client pour faire nos tests

CarteDeVisiteCMP test;

54 // Recherche par le prefix de la personne

Collection c1 = home.findByPrefix(prefix );

return c1;

}

59 catch (Exception e) {

System.err.println("Erreur : " + e);

}

return null;

}

64

public void ejbCreate () {}

public void ejbRemove () {}

public void ejbActivate () {}

public void ejbPassivate () {}

69 public void setSessionContext(SessionContext sc) {}

}

Listing 9.20 – Fichier ConsultatorBean.java

Descripteur J2EE

<?xml version ="1.0" encoding ="ISO -8859 -1"? >

<ejb -jar >

<description >Descripteur de deploiement du consultator </ description >

<display -name >Consultator </display -name >

5 <enterprise -beans >

<session >

<description >Consultator </ description >

<display -name >Consultator </display -name >

<ejb -name >Consultator </ejb -name >

10 <home >consultators.ConsultatorHome </home >

<remote >consultators.Consultator </remote >

Page 25: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.4. LA PARTIE METIER (SUITE) - STATELESS SESSION BEAN 25

<ejb -class >consultators.ConsultatorBean </ejb -class >

<session -type >Stateless </session -type >

<transaction -type >Container </ transaction -type >

15 </session >

</enterprise -beans >

<assembly -descriptor >

<container -transaction >

<method >

20 <ejb -name >Consultator </ejb -name >

<method -name >*</method -name >

</method >

<trans -attribute >Required </trans -attribute >

</container -transaction >

25 </assembly -descriptor >

</ejb -jar >

Listing 9.21 – Fichier ejb-jar.xml

Descripteur Jonas

<?xml version ="1.0" encoding ="ISO -8859 -1"? >

<jonas -ejb -jar >

<jonas -session >

4 <ejb -name >Consultator </ejb -name >

<jndi -name >MyConsultator </jndi -name >

</jonas -session >

</jonas -ejb -jar >

Listing 9.22 – Fichier jonas-ejb-jar.xml

9.4.2 Client d’un session bean

Nous commencons a etre rode... aucune difficulte particuliere.

package consultators;

3 import java.util.Properties;

import javax.naming.InitialContext;

import javax.naming.Context;

import javax.rmi.PortableRemoteObject;

8 import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.IOException;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

13

import java.util .*;

import carte_cmp .*;

public class ConsultatorClient {

18

public static void main(String args []) {

Page 26: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

26 CHAPITRE 9. PREMIERS PAS J2EE

try {

23 // Recherche de l’interface home de l’EJB

Context initialContext = new InitialContext ();

Object objref = initialContext.lookup("MyConsultator");

// Reference a l’EJB

28 ConsultatorHome home = (ConsultatorHome)

PortableRemoteObject.narrow(objref , ConsultatorHome.class );

Consultator myConsultator = home.create ();

// On va chercher des gens

33 InputStreamReader isr = new InputStreamReader ( System.in );

BufferedReader br = new BufferedReader ( isr );

boolean isQuit = false;

38 while (isQuit == false){

System.out.println("1. Rechercher par nom");

System.out.println("2. Rechercher par prefixe (sur le nom)");

System.out.println("3. Quitter");

System.out.println(">");

43

String choice = null;

choice = br.readLine ();

if (choice.equals("1")){

System.out.println("Recherche par nom ...");

48 String nom = null;

System.out.println("Entrez le nom : ");

nom = br.readLine ();

CarteDeVisiteCMP test = null;

Collection cl = myConsultator.rechercherNom(nom);

53 System.out.println("recherche sur le nom : "+nom);

if(cl != null){

Iterator iLast = cl.iterator ();

while (iLast.hasNext ()) {

test = iLast.next ();

58 System.out.println("->" + test.getPrenom ());

}

}

else{

System.out.println("Echec de recherche ...");

63 }

}

else if (choice.equals("2")){

System.out.println("Recherche par prefixe ...");

String prefix = null;

68 System.out.println("Entrez le prefixe : ");

prefix = br.readLine ();

CarteDeVisiteCMP test = null;

Collection c2 = myConsultator.rechercherPrefix(prefix );

System.out.println("recherche sur le prefix : "+prefix );

73 if(c2 != null){

Iterator iLast2 = c2.iterator ();

while (iLast2.hasNext ()) {

test = iLast2.next ();

Page 27: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.4. LA PARTIE METIER (SUITE) - STATELESS SESSION BEAN 27

System.out.println("->" + test.getPrenom ());

78 }

}

else {

System.out.println("Echec de recherche ...");

}

83 }

else if (choice.equals("3")){

System.out.println("Bye bye ...");

isQuit = true;

}

88 else{

System.out.println("Choix incorrect ...");

}

}

} catch (Exception e) {

93 System.err.println("Erreur : " + e);

System.exit (2);

}

}

}

Listing 9.23 – Fichier ConsultatorClient.java

9.4.3 Compilation, deploiement et execution

A vous de jouer. Voici un exemple d’execution :

LINUX :~/ Consultator > ./ manage.sh run

## Runnning client ...

3 ClientContainer.info : Starting client ...

1. Rechercher par nom

2. Rechercher par prefixe (sur le nom)

3. Quitter

>

8 1

Recherche par nom...

Entrez le nom :

mosser

recherche sur le nom : mosser

13 ->sebastien

1. Rechercher par nom

2. Rechercher par prefixe (sur le nom)

3. Quitter

>

18 2

Recherche par prefixe ...

Entrez le prefixe :

m

recherche sur le prefix : m

23 ->sebastien

1. Rechercher par nom

2. Rechercher par prefixe (sur le nom)

3. Quitter

>

Page 28: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

28 CHAPITRE 9. PREMIERS PAS J2EE

28 3

Bye bye ...

9.5 La partie presentation - servlet

9.5.1 Principe

Apres avoir construit plusieurs clients lourds, il nous semble essentiel de pouvoir offriraux utilisateurs eventuels la possibilite de consulter les cartes depuis un client leger.

Dans l’approche J2EE, les clients legers sont offerts par exemple par l’utilisation deservlet qui generent des pages html consultables depuis n’importe quel butineur web.

9.5.2 Ecriture de la servlet

Les differents repertoires utilises sont :– src : contient les sources de la servlet– bin/WEB-INF/ : contient les descripteurs de deploiements– bin/WEB-INF/classes : le code compile de la servlet.La servlet implementee reagira a une requete GET3 et son code est le suivant :

1 import java.io.PrintWriter;

import java.io.IOException;

import java.util.Collection;

import java.util.Iterator;

import javax.servlet.ServletException;

6 import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import javax.naming.Context;

11 import javax.naming.InitialContext;

import javax.rmi.PortableRemoteObject;

import consultators .*;

import carte_cmp .*;

16

public class Consult extends HttpServlet {

protected void doGet(HttpServletRequest req , HttpServletResponse res)

throws ServletException , IOException {

21 res.setContentType("text/html");

PrintWriter out = res.getWriter ();

head(out);

Object prefix = req.getParameter("prefix");

look(prefix , out);

26 foot(out);

}

private void look(Object p, PrintWriter out) {

3Il est possible de construire une servlet reagissant a une requete POST en implementant unemethode doPost.

Page 29: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.5. LA PARTIE PRESENTATION - SERVLET 29

if (p == null) {

31 out.println("You must enter a name !");

return;

}

String prefix = (String) p;

if (prefix.equals("")) {

36 out.println("You must enter a name !");

return;

}

// Initializing context

41 Context initialContext = null;

try {

initialContext = new InitialContext ();

}

catch(Exception e) {

46 out.println("<h3 > Unable to find InitialContext !</h3 >");

out.println(e + "<br />");

return;

}

51 // Connecting to the bean

ConsultatorHome home = null;

try {

home = (ConsultatorHome)

PortableRemoteObject.narrow(

56 initialContext.lookup("MyConsultator"),

ConsultatorHome.class);

}

catch(Exception e) {

out.println("<h3 > Unable to retrieve MyConsultator !</h3 >");

61 out.println(e + "<br />");

return;

}

// Instanciation

66 Consultator consult = null;

try {

consult = home.create ();

}

catch(Exception e) {

71 out.println("<h3 > Unable to create a Consultator"

+ " instance !</h3 >");

out.println(e + "<br />");

return;

}

76

// Doing the search ...

Collection result = null;;

try {

result = consult.rechercherPrefix(prefix );

81 out.println("<h2 > Search Result for " + prefix + "</h2 >");

printResult(result , out);

}

catch(Exception e) {

out.println("<h3 > Unable to invoke the Consultator !</h3 >");

Page 30: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

30 CHAPITRE 9. PREMIERS PAS J2EE

86 out.println(e + "<br />");

return;

}

91 }

private void printResult(Collection c, PrintWriter out)

throws Exception {

if (c.size() == 0) {

96 out.println("<strong > No match found ! </strong >");

}

Iterator i = c.iterator ();

while (i.hasNext ()) {

CarteDeVisiteCMP card = (CarteDeVisiteCMP) i.next ();

101 out.println("<h4 > " + card.getNom () + " " + card.getPrenom ()

+ " </h4>");

out.println("<ul >");

out.println("<li > Telephone : "+ card.getPhone () +"</li >");

out.println("<li > Email : "+ card.getEmail () +"</li >");

106 out.println("</ul >");

}

}

111

private void head(PrintWriter out) {

out.println("<html ><head ><title >Card Consultation Form </title >"

+" </head >");

out.println("<body >");

116 out.println("<h1 >Looking for Someone ?</h1 ><br >");

out.println("<form method =\" get\">");

out.println("<p>");

out.println("Name : &nbsp; "

+ "<input type =\" text\" name =\" prefix \" />");

121 out.println("<br /> <input type =\" submit \" value =\" Search !\"/>");

out.println("</p>");

out.println("</form >");

}

126 private void foot(PrintWriter out) {

out.println("</body >");

out.println("</html >");

out.close ();

}

131 }

Listing 9.24 – Fichier Consult.java

Descripteur J2EE

Le descripteur permet de decrire l’URL associee a la servlet ainsi que les liens avec lesbeans utilises.

<?xml version ="1.0" encoding ="ISO -8859 -1"? >

Page 31: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

9.5. LA PARTIE PRESENTATION - SERVLET 31

<web -app xmlns ="http :// java.sun.com/xml/ns/j2ee"

xmlns:xsi="http ://www.w3.org /2001/ XMLSchema -instance"

4 xsi:schemaLocation ="http :// java.sun.com/xml/ns/j2ee

http :// java.sun.com/xml/ns/j2ee/web -app_2_4.xsd"

version ="2.4" >

<servlet >

<servlet -name >CardManager </servlet -name >

9 <servlet -class >Consult </servlet -class >

</servlet >

<servlet -mapping >

<servlet -name >CardManager </servlet -name >

<url -pattern >/card/consult </url -pattern >

14 </servlet -mapping >

<ejb -ref >

<ejb -ref -name >Consultator </ejb -ref -name >

<ejb -ref -type >Session </ejb -ref -type >

<home >consultators.ConsultatorHome </home >

19 <remote >consultators.Consultator </remote >

<ejb -link >Consultator.jar </ejb -link >

</ejb -ref >

</web -app >

Listing 9.25 – Fichier web.xml

Descripteur Jonas

Ce descripteur decrit les liens avec le session bean utilise.

<?xml version ="1.0" encoding ="ISO -8859 -1"? >

<jonas -web -app xmlns ="http :// www.objectweb.org/jonas/ns"

3 xmlns:xsi="http ://www.w3.org /2001/ XMLSchema -instance"

xsi:schemaLocation ="http :// www.objectweb.org/jonas/ns

http :// www.objectweb.org/jonas/ns/jonas -web -app_4_0.xsd" >

<jonas -ejb -ref >

<ejb -ref -name >Consultator </ejb -ref -name >

8 <jndi -name >MyConsultator </jndi -name >

</jonas -ejb -ref >

<host >localhost </host >

<context -root >web -application </context -root >

</jonas -web -app >

Listing 9.26 – Fichier jonas-web.xml

9.5.3 Compilation et deploiement

Les servlets sont chargees comme des applications web, et doivent etre packagees commetelles. Ainsi, on archivera le contenu du repertoire bin dans un fichier war (pour WebArchive) et non dans un jar (Java Archive)4.

4Un fichier .war se genere comme un fichier .jar en utilisant la commande jar

Page 32: Premiers pas J2EE - i3s.unice.frriveill/mes-cours/serveurs-entreprises/javaee/... · plate-forme respectant les sp eci cations J2EE (Java 2 Enterprise Edition). Pour cela nous allons

32 CHAPITRE 9. PREMIERS PAS J2EE

Compilation

La servlet accede au session bean et entity bean via son interface remote qu’il fautdonc copier dans le repertoire src.

TODO pourquoi aussi l’entity bean ?TODO pourquoi pas via un proxy ?

LINUX:~> javac -cp $JONAS\_ROOT/lib/commons/j2ee.servlet.jar -d bin/WEB -INF/classes src/*java

LINUX:~> cp web.xml jonas -web.xml bin/WEB -INF/.

3 LINUX:~> cd bin

LINUX :~/bin > jar cf ../ Consult.war *

LINUX :~/bin > cd ..

Chargement

LINUX:~> mv Consult.war >JONAS_ROOT/webapps /.

LINUX:~> cd $JONAS_ROOT/webapps

LINUX:~> jonas admin -a Consult.war

Execution

Il suffit d’ouvrir son butineur prefere, et de se rendre a l’adresse decrite dans le fichierde mapping : http://localhost:9000/web-application/card/consult.

9.6 Pour aller plus loin

– Ecrire une servlet pour l’administration de l’annuaire.– Utiliser la securite J2EE– Utiliser les transactions