Exercice 3
Enterprise beans coopératifs

[<<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.

Modifier le bean de session

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é.

 

Des beans travaillant ensemble

CalcHome

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;
}

Calc

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;
}

CalcBean

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() { }
}

Modifier la servlet

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();
 }

Compilation

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.

Compiler le bean de session

Unix

#!/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

Windows

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

Compiler la servlet

Unix:

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 

Windows:

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

Démarrer les serveurs et les outils

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 :

Unix

j2sdkee1.2.1/bin/j2ee -verbose
j2sdkee1.2.1/bin/deploytool
j2sdkee1.2.1/bin/cloudscape -start

Windows

j2sdkee1.2.1\bin\j2ee -verbose
j2sdkee1.2.1\bin\deploytool
j2sdkee1.2.1\bin\cloudscape -start

Assemblage de l'application

Les étapes de cette section incluent :

Créer une nouvelle application J2EE

Plutôt que de mettre à jour l'application J2EE des exercices 1 et 2, ces étapes créent une nouvelle application J2EE.

SupprimerBonusApp:

Créer l'application 2BeansApp :

Sélecteur de fichier New Application :

Créer un nouveau composant web

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,

File Menu:

Introduction :

War File General Properties :

War File General Properties :

Choose Component Type: .

Component General Properties :

Component Initialization Parameters .

Component Aliases :

Inspecting window:

Empaqueter les beans de session et d'entité dans un fichier JAR

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.

Créer le JAR avec le bean de session

Avec l'application 2BeansApp sélectionnée,

File Menu:

Introduction :

EJB JAR :

Enterprise Bean JAR classes :

EJB JAR :

General :

Environment Entries:

Enterprise Bean References:

Resource References:

Security:

Transaction Management :

Review Settings:

Local Applications:

Add the Entity Bean

Avec l'application 2BeansApp sélectionnée,

File Menu:

Introduction :

EJB JAR :

Enterprise Bean JAR classes :

EJB JAR :

General :

Entity Settings:

Environment Entries:

Enterprise Bean References:

Resource References:

Security:

Transaction Management :

Review Settings:

Local Applications:

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 :

Local Applications window:

Inspecting window:

Deployment Settings window:

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,

Vérification et déploiement de l'application J2EE

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.

Verify:

Deploy:

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.

Exécuter l'application J2EE

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.

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]