[<<Retour] [Sommaire] [Suivant>>]
Dans l'exercice 2 Un bean d'entité simple, la servlet devait chercher et créer un bean de session pour effectuer le calcul d'un bonus, et ensuite chercher et créer un bean d'entité où stocker la valeur du bonus et le numéro de sécurité social correspondant. Cet exercice modifie l'exemple pour que le bean de session cherche et crée le bean d'entité. Comme le bean de session et le bean d'entité travaillent ensemble, ils seront livrés à l'intérieur d'un seul fichier JAR pour le déploiement.
Note: Certaines personnes ont eu des problèmes pour que cet exercice fonctionne avec 2 beans dans un fichier JAR. Si cela vous arrive, supprimer le fichier JAR avec les 2 beans et mettez chaque beans dans un fichier JAR séparé. Vous aurez peut-être besoin de stopper et redémarrer le serveur avant de pouvoir générer le SQL et déployer.
Dans cette exercice, et comme
présenté dans l'illustration
14, le bean d'entité est un client du bean de session. Cela veut
dire que le bean d'entité reçoit ses données du bean de
session plutôt que de la BonusServlet comme
c'était le cas dans l'exercie 2 Un
bean d'entité simple. Ainsi, la méthode
calcBonus du bean de session est modifié pour prendre le numéro
de sécurité sociale comme argument et créer le bean d'entité.
L'interface
CalcHome reste inchangée. Elle comporte la même méthode
create qui retourne une instance d'interface distante.
package Beans; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome;
public interface CalcHome extends EJBHome {
public Calc create()
throws CreateException, RemoteException;
}
La méthode calcBonus de
l'interface Calc est modifiée pour prendre un numéro de sécurité
sociale comme argument. Cela permet à CalcBean
de transmettre le bonus et le numéro de sécurité sociale
au bean d'entité après avoir calculé la valeur du bonus.
Une nouvelle méthode getRecord est ajoutée
pour permettre à CalcBean de trouver un bean d'entité par sa clé
primaire (son numéro de sécurité sociale).
Vous remarquerez que la signature
de la méthode calcBonus mentionne DuplicateKeyException
et CreateException . Cela est fait pour que la
BonusServlet puissent intercepter et gérer ces dexu conditions
d'exception. DuplicateKeyException descend de CreateException
. Si vous concevez la méthode calcBonus pour
déclencher DuplicateKeyException , mais interceptez
CreateException , DuplicateKeyException n'est
pas déclenchée. Pour contourner ce problème, calcBonus
prend en compte les deux conditions exceptions DuplicateKeyException et CreateException
.
package Beans; import javax.ejb.EJBObject; import java.rmi.RemoteException; import javax.ejb.DuplicateKeyException; import javax.ejb.CreateException;
public interface Calc extends EJBObject {
public Bonus calcBonus(int multiplier,
double bonus,
String socsec)
throws RemoteException,
DuplicateKeyException,
CreateException;
public Bonus getRecord(String socsec)
throws RemoteException;
}
Le code utilisé pour créer
le bean d'entité est déplacé de la BonusServlet
à la méthode calcBonus ainsi le bonus
et le numéro de sécurité sociale peuvent être écrits
dans le bean d'entité après avoir été calculé.
La variable homebonus est une variable d'instance
utilisée par la méthode calcBonus pour
localiser le bean d'entité et dans la méthode getRecord pour localiser le bean d'entité
correspondant au numéro de sécurité sociale.
package Beans;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.ejb.DuplicateKeyException;
import javax.ejb.CreateException;
public class CalcBean implements SessionBean {
BonusHome homebonus;
//Throw DuplicateKeyException and CreateException
//so BonusServlet can catch and handle these
//exception conditions.
public Bonus calcBonus(int multiplier,
double bonus, String socsec)
throws DuplicateKeyException,
CreateException {
Bonus theBonus = null;
double calc = (multiplier*bonus);
try {
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("bonus");
homebonus = (BonusHome)
PortableRemoteObject.narrow(
objref, BonusHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
//Store data in entity bean
try {
theBonus = homebonus.create(calc, socsec);
} catch (java.rmi.RemoteException e) {
String message = e.getMessage();
e.printStackTrace();
}
return theBonus;
}
public Bonus getRecord(String socsec) {
Bonus record = null;
//Use primary key to retrieve data from entity bean
try {
record = homebonus.findByPrimaryKey(socsec);
} catch (java.rmi.RemoteException e) {
String message = e.getMessage();
} catch (javax.ejb.FinderException e) {
e.printStackTrace();
}
return record;
}
public void ejbCreate() { }
public void setSessionContext(
SessionContext context){
}
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbLoad() { }
public void ejbStore() { }
}
Cette version de la BonusServlet
est très similaire à la version de la
Leçon 2 "Un bean d'entité simple avec quelques modifications
dans les méthodes init et doGet. La méthode
init de cet exercice cherche seulement le bean de
session CalcBean.
public class BonusServlet extends HttpServlet {
CalcHome homecalc;
//Need Bonus variables because CalcBean methods
//called in the doGet method return instances
//of type Bonus
Bonus theBonus, record;
public void init(ServletConfig config)
throws ServletException{
try {
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc = (CalcHome)
PortableRemoteObject.narrow(
objref, CalcHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
}
La clause
try de la méthode doGet calcule le bonus,
créer une interface home de bean de session, et appelle les méthodes
calcBonus et getRecord .
Si ces méthodes se déroulent avec succès, une page HTML
avec les données retirées du bean d'entité est affichée.
Si l'exception DuplicateKeyException est déclenchée
par la méthode calcBonus , une page HTML contenant
le numéro de sécurité sociale et le multiplicateur associé
est retournée, avec un message d'exception, Duplicate
primary key .
Comme dans la leçon précédente
Un bean d'entité simple, l'instruction
catch intercepte et gère les cas de clé
primaire multiples (numéros de sécurité sociale).
try {
Calc theCalculation;
//Retrieve Bonus and Social Security Information
String strMult = request.getParameter(
"MULTIPLIER");//Calculate bonus
Integer integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
socsec = request.getParameter("SOCSEC");
//Calculate bonus
double bonus = 100.00;
theCalculation = homecalc.create();
//Call session bean
//Pass 3 parameters:multiplier, bonus, and socsec
theBonus = theCalculation.calcBonus(
multiplier, bonus, socsec);
record = theCalculation.getRecord(socsec);
//Display data returned by session bean
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec retrieved: " +
record.getSocSec() + "<P>");
out.println("<P>Bonus Amount retrieved: " +
record.getBonus() + "<P>");
out.println("</BODY></HTML>");
} catch (javax.ejb.DuplicateKeyException e) {
String message = e.getMessage();
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec passed in: " + socsec +
"<P>");
out.println("<P>Multiplier passed in: " +
multiplier + "<P>");
out.println("<P>Duplicate primary key<P>");
out.println("</BODY></HTML>");
} catch (Exception CreateException) {
CreateException.printStackTrace();
}
Commencez par compiler le bean de session et la servlet. Se référer à l'exercice 1 pour le paramètrage des variables d'environnement PATH et CLASSPATH, ainsi que sur l'endroit où placer les fichiers sources.
#!/bin/sh
cd /net/home/lmaitre/j2ee
J2EE_HOME=/net/home/lmaitre/J2EE/j2sdkee1.2.1
CPATH=.:$J2EE_HOME/lib/j2ee.jar
javac -d . -classpath "$CPATH" Beans/CalcBean.java
Beans/CalcHome.java Beans/Calc.java
cd \net\home\lmaitre\J2EE
set J2EE_HOME=\net\home\lmaitre\J2EE\j2sdkee1.2.1
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar
javac -d . -classpath %CPATH% Beans/CalcBean.java
Beans/CalcHome.java Beans/Calc.java
cd /net/home/lmaitre/J2EE/ClientCode
J2EE_HOME=/net/home/lmaitre/J2EE/j2sdkee1.2
CPATH=.:$J2EE_HOME/lib/j2ee.jar:
/net/home/lmaitre/J2EE
javac -d . -classpath "$CPATH" BonusServlet.java
cd \net\home\lmaitre\J2EE\ClientCode set J2EE_HOME=\net\home\lmaitre\J2EE\j2sdkee1.2 set CPATH=.;%J2EE_HOME%\lib\j2ee.jar:\net\home\lmaitre\J2EE javac -d . -classpath %CPATH% BonusServlet.java
Pour exécuter cet exemple vous devez démarrer le serveur J2EE, l'outil de déploiement et la base de données Cloudscape. Dans des fenêtres différentes, tapez les commandes suivantes :
j2ee -verbose deploytool cloudscape -start
Si ça ne fonctionnait pas, tapez ceci à partir du répertoire de J2EE :
j2sdkee1.2.1/bin/j2ee -verbose j2sdkee1.2.1/bin/deploytool j2sdkee1.2.1/bin/cloudscape -start
j2sdkee1.2.1\bin\j2ee -verbose j2sdkee1.2.1\bin\deploytool j2sdkee1.2.1\bin\cloudscape -start
Les étapes de cette section incluent :
Plutôt que de mettre à jour l'application J2EE des exercices 1 et 2, ces étapes créent une nouvelle application J2EE.
Créer l'application 2BeansApp :
2BeansApp apparaît comme nom (display name). EAR
de l'application. Sélecteur de fichier New Application :
EAR de
l'application/net/home/lmaitre/J2EE/export . 2BeansApp.ear . Maintenant suivez ces étapes pour créer le fichier WAR. Ces étpaes sont tirèes de l'exercie 1 et récaptiluées ci-dessous. avec l'application 2BeansApp sélectionnée,
ClientCode et ajouter bonus.html
Next ClientCode et ajouter BonusServlet.class
Finish . Component General Properties :
Component Initialization Parameters .
Dans cette leçon, vous allez mettre le bean de session et le bean d'entité dans le même fichier JAR. Pour faire cela commencez par créer un fichier JAR avec uniquement le bean de session et ajouter ensuite le bean d'entité au fichier JAR.
Avec l'application 2BeansApp
sélectionnée,
2BeansApp apparaît dans le champ Enterprise
Bean will go in . 2BeansJar comme nom. Add . Calc.class
Add .
CalcBean.class
Add .
CalcHome.class
Add .
Beans/Calc.class
, Beans/CalcHome.class , et
Beans/CalcBean.class sont affichés. OK .
CalcBean est le nom de la classe,
Beans.CalcHome est l'interface Home, et Beans.Calc l'interface distante (Remote).
CalcBean comme nom. Next .
Next . Ce simple bean de session n'utilise pas de propriétés
configurables (variables d'environnement). Next . Ce simple bean de session ne contacte pas de
base de données ou d'objet session JavaMail. Container-managed transactions (si ce n'est pas déjà
sélectionné). calcBonus , et getRecord
comme requis (required). Cela veut dire que le conteneur démarre automatiquement
une nouvelle transaction avant d'appeler ces méthodes et que la transaction
est effective juste avant la fin de la méthode. On peut trouver plus
d'information sur ce sujet dans le chapitre 6 du Enterprise JavaBeans Developer's
Guide. 2BeansApp .
JNDI names , donner à CalcBean le nom JNDI calcs
, et valider en appuyant sur la touche Enter. Avec l'application
2BeansApp sélectionnée,
2BeansJar est affiché dans le champ Enterprise
Bean will go in. Ce paramétrage va ajouter le nouveau bean au fichier
JAR plutôt que de mettre le beqn dans son propre fichier JAR. Add (celui situé après la fenêtre
Contents). Bonus.class
Add .
BonusBean.class
Add .
BonusHome.class
Add .
Beans/Bonus.class
, Beans/BonusHome.class , et
Beans/BonusBean.class sont affichés. OK .
Beans.BonusBean est le nom de la classe,
Beans.BonusHome le nom de l'interface Home et Beans.Bonus l'interface distante. BonusBean comme nom. Next .
Container managed persistence .
bonus et
socsec . La classe de la clé primaire est
java.lang.String , et nom du champ de clé primaire est socsec . Notez que la clé primaire doit
avoir un type de classe. Les types primitifs ne sont pas autorisés
pour les clés primaires.Next .
Container-managed transactions (si ce n'est pas déjà
sélectionné). create , findByPrimaryKey
, getBonus et getSocSec
comme requis. Cela indique au contenur de démarrer une transaction
avant d'exécuter ces méthodes. La transaction est opérée
just avant la fin des méthodes.Next .
2BeansApp .
JNDI names
, donner à BonusBean le nom JNDI de bonus
et àCalcBean le nom JNDI de calcs
Avant que l'application J2EE puisse être déployée, vous devez spécifier les paramètres de déploiement du bean d'entité et générer le SQL. Voilà comment faire :
jdbc/Cloudscape (avec un C majuscule
à Cloudscape) comme nom JNDI de la base données (Database JNDI
name)Create table on deploy et Delete
table on Deploy sont sélectionnéesGenerate SQL. Note: Si vous obtenez une erreur et que la connection est refusée assurez vous de suivre les informations de Start the Platform and Tools.
Quand la génération du SQL est terminée,
findByPrimaryKey dans la zone des méthodes
de l'EJB. SELECT "socsec" FROM
"BonusBeanTable" WHERE "socsec"=? . Le point d'interrogation (?) représente
le paramètre passé à la méthode findByPrimaryKey. OK .
Avant de pouvoir déployer l'application, c'est une bonne idée de la vérifier. Le vérificateur peut indiquer des erreurs dans les composants de l'application, telles que de méthodes manquantes que le conteneur ne peut localiser.
Note : Si vous obtenez une erreur de sauvegarde (Save error) quand vous vérifiez ou déployer, arrêtez tout et redémarrez les serveurs et utilitaires de déploiement.
2BeansApp sélectionée, choisir
Verifier dans le menu Tools. OK . La fenêtre
ne devrait pas indiquer de tests en échec. Deploy Application . Une boite
de dialogue Deploy BonusApp apparaît. Note: Ne cochez pas la case Return Client Jar. La seule fois où vous aurez besoin de cocher cette case est lorsque vous utiliserez la persistance gérée par les beans ou que vous déployerez une application autonome comme programme client. Cet exemple utilise une page HTML et une servlet donc cette case ne doit pas être cochée. Sélectionner cette option crée un fichier JAR avec les informations de déploiement nécessaire pour une application autonome.
Next . calcs pour CalcBean et bonus pour
BonusBean . Si ce n'est pas le cas, tapez les noms JNDI vous mêmes
et valider en appuyant sur la touche Entrée.
Next . Assurez vous que le nom du Context Root est BonusRoot . Si ce n'est pas le cas, tapez les
noms JNDI vous mêmes et valider en appuyant sur la touche Entrée.
Next . Finish pour démarrer le déploiement. Une
boîte de dialogue avec l'état d'avancement du déploiement
apparaît.OK . Le serveur web fonctionne sur le port 8000 par
défaut. Pour ouvrir la page bonus.html diriger
votre navigateur sur http://localhost:8000/BonusRoot/bonus.html
, qui est l'endroit où l'outil de déploiement à mis la
page HTML.
Submit . BonusServlet traite
vos données et retourne une page HTML avec le calcul du bonus.Bonus Calculation Soc Sec retrieved: 777777777 Bonus Amount Retrieved: 200.0
Si vous saisissez le même numéro de sécurité sociale par la suite, vous obitendrez quelque chose de similaire à :
Bonus Calculation Soc Sec passed in: 777777777 Multiplier passed in: 2 Duplicate primary key
[RETOUR]