Exercice 8 : Un bean de session avec état, CartEJB

[<<RETOUR] [SOMMAIRE] [SUIVANT>>]

L'exemple de bean de session CartEJB représente un caddy dans un magasin de livres en ligne. Le client du bean peut ajouter un livre au caddy, retirer un livre, ou lire le contenu du caddy. Pour construire CartEJB, nous allons avoir besoin des programmes suivants :

Tous les beans de session requierts une classe dérivée des beans de session. Tous les beans d'entreprise qui proposent un accès distants requierts une une interface home et une remote interfqce. pour répondre aux bseoins de certqines fonctions, les beans peuvent avoir recours à des classes utilitaires. Le bean de session CartEJB utilise deux classes utilitaires, BookException et IdVerifier, qui sont décrites dans la section Classes utilitaires.

Le code source de cet exemple est dans le répertoire j2eetutorial/examples/src/ejb/cart . Pour compiler le programme allez dansj2eetutorial/examples et tapez ant cart. Un fichier d'exemple CartApp.ear est disponible dans le répertoire j2eetutorial/examples/ears.

Classe du bean session

La classe du session bean de cet exercice est appeléeCartBean. Comme pour tout session bean la classe CartBean doit satisfaire ces contraintes :

Le code source de la classe CartBean est le suivant :

import java.util.*;
import javax.ejb.*;

public class CartBean implements SessionBean {

   String customerName;
   String customerId;
   Vector contents;

   public void ejbCreate(String person) 
      throws CreateException {

      if (person == null) {
         throw new CreateException("Null person not allowed.");
      }
      else {
         customerName = person;
      }

      customerId = "0";
      contents = new Vector();
   }

   public void ejbCreate(String person, String id) 
      throws CreateException {

      if (person == null) {
         throw new CreateException("Null person not allowed.");
      }
      else {
         customerName = person;
      }

      IdVerifier idChecker = new IdVerifier();
      if (idChecker.validate(id)) {
         customerId = id;
      }
      else {
         throw new CreateException("Invalid id: "+ id);
      }

      contents = new Vector();
   }

   public void addBook(String title) {
      contents.addElement(title);
   }

   public void removeBook(String title) throws BookException {

      boolean result = contents.removeElement(title);
      if (result == false) {
         throw new BookException(title + "not in cart.");
      }
   }

   public Vector getContents() {
      return contents;
   }

   public CartBean() {}
   public void ejbRemove() {}
   public void ejbActivate() {}
   public void ejbPassivate() {}
   public void setSessionContext(SessionContext sc) {}

} 
 

L'interface SessionBean

L'interface SessionBean étend l'interface EnterpriseBean , qui étend elle-même l'interface Serializable . L'interface SessionBean déclare les méthodes ejbRemove, ejbActivate, ejbPassivate, et setSessionContext. La classe CartBean n'utilise pas ces méthodes mais elle doit les déclarer car elles sont déclarées dans l'interface SessionBean. En conséquence ces méthodes sont vides dans la classe CartBean.

La méthode ejbCreate

Comme un bean d'entreprise réside dans un conteneur d'EJB, un client ne peut pas instancier directement un bean. Seul le conteneur d'EJB peut instancier un bean d'entreprise. Durant l'instantiation le programme effectue les étapes suivantes :

  1. Le client appelle la méthode create sur une instance de l'interface home de l'objet.
       Cart shoppingCart = home.create("Duke DeEarl","123");
     
  2. Le conteneur d'EJB instancie le bean d'entreprise.
  3. Le conteneur d'EJB appelle la méthode ejbCreate de CartBean:
       public void ejbCreate(String person, String id) 
          throws CreateException {
    
          if (person == null) {
             throw new CreateException("Null person not allowed.");
          }
          else {
             customerName = person;
          }
    
          IdVerifier idChecker = new IdVerifier();
          if (idChecker.validate(id)) {
             customerId = id;
          }
          else {
             throw new CreateException("Invalid id: "+ id);
          }
    
          contents = new Vector();
       }
     
    

Habituellement, la méthode ejbCreate intialise l'état du bean d'entreprise.La méthode ejbCreate précédente par exemple initialise les variables customerName et customerId avec les arguments passés aux méthodes create.

Un bean d'entreprise doit avoir une ou plusieurs méthodes ejbCreate . Les signatures de ces méthodes doivent obéir aux règles suivantes :

  • L'accès doit être public.
  • Le type de retour doit être void.
  • Si le bean autorise l'accès distant, ces arguments doievent être légaux pour la'API Java Remote Method Invocation ("Java RMI").
  • Le modificateur ne peut être static oufinal.

La clause throws peut inclure l'exception javax.ejb.CreateException ou d'autres exceptions spécifiques à votre application. La méthode ejbCreate déclenche habituellement CreateException si un paramètre onvalide à été passé.

Méthodes métiers

L'objet principal d'un bean de session est d'effectuer des tâches métiers pour un client. Le client appelle des méthodes métiers sur la référence d'objet distant retournée par la méthode create. Du point de vue du client, les méthodes métiers donnent l'impression d'être exécutées localement mais elles sont en réalité déclenchées à distance sur le bean de session. Les fragments de code suivant montre ds exemples d'utilisation des ces méthodes dans le programme CartClient :

Cart shoppingCart = home.create("Duke DeEarl", "123");
...
shoppingCart.addBook("The Martian Chronicles"); 
shoppingCart.removeBook("Alice In Wonderland");
bookList = shoppingCart.getContents();
 

La classe CartBean implémente ces méthodes dans les fragments de code suivant :

public void addBook(String title) {
   contents.addElement(new String(title));
}

public void removeBook(String title) throws BookException {
   boolean result = contents.removeElement(title);
   if (result == false) {
      throw new BookException(title + "not in cart.");
   }
}

public Vector getContents() {
   return contents;
}
 
La signature de cette méthode métier doit juste se conformer à ces règles :
  • Le nom de la méthode ne pas entrer en conflit avec un de ceux de l'architecture EJB, comme ejbCreate ou ejbActivate.
  • L'accès doit être public.
  • Si le bean autorise un accès distant, les arguments et valeurs retournées doivent être légales pour l'API RMI.
  • Le modificateur ne doit pas être static ou final.

La clause throws peut inclure des exceptions que vous définissez dans votre application. La méthode removeBook par exemple déclenche BookException si le livre n'est pas dans le caddy.

Pour indiquer un problème système, comme l'imossibilité de se connecter à la base de données, une méthode métier peut déclencher javax.ejb.EJBException. Quand une méthode métier déclenche une EJBException, le container l'enrobe dans une RemoteException, qui est interceptée par le client. Le container n'enrobe pas des exceptions d'application comme BookException. Comme EJBException est une sousclasse de RuntimeException, vous n'avez pas besoin de l'inclure dans les clauses throws de vos méthodes métier.

Interface Home

L'interface Home doit étendre javax.ejb.EJBHome. Pour un bean de session, le propos de l'interface Home est de définir les méthodes create qu'un client distant peut invoquer.Le programme CartClient par exemple appelle cette méthode create :

Cart shoppingCart = home.create("Duke DeEarl", "123");
 

Chaque méthode create de l'interface Home a une méthode correspondante ejbCreate dans la classe du bean. Les signatures méthodes ejbCreate de la classe CartBean suivent :

public void ejbCreate(String person) throws CreateException   
... 
public void ejbCreate(String person, String id) 
   throws CreateException 
 

Comparez ces singatures d'ejbCreate avec celles des méthodes create de l'interface CartHome :

import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface CartHome extends EJBHome {
   Cart create(String person) throws 
                  RemoteException, CreateException;
   Cart create(String person, String id) throws 
                  RemoteException, CreateException; 
}
 

Les signatures des méthodes ejbCreate et create sont similaires, mais différent sur quelques points importants. Les règles pour définir les signatures des méthodes create de l'interface home sont les suivantes.

  • Le nombre et le type d'arguments dans la méthode create doivent correspondre à ceux de la méthode ejbCreate.
  • Les arguments et le type de retour de la méthode create doivent être valides pour RMI.
  • Une méthode create renvoit une interface distante du type de l'enterprise bean (mais ejbCreate retourne void.)
  • La clause throws de la méthode create doit inclure les exceptions java.rmi.RemoteException et javax.ejb.CreateException.

Interface distante (Remote)

L'interface distante étend javax.ejb.EJBObject et définit les méthodes métiers qu'un client distant peut appeler. Voici le code source de l'interface distante Cart :

import java.util.*;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface Cart extends EJBObject {
 
   public void addBook(String title) throws RemoteException;
   public void removeBook(String title) throws 
                     BookException, RemoteException;
   public Vector getContents() throws RemoteException;
}
 

Les définitions de méthode d'une interface distante doivent suivre ces règles :

  • Chaque méthode de l'interface distante doit correspondre à une méthode implémentée dans la classe du bean d'entreprise.
  • La signature des méthodes de l'interface distante doit être identique aux signatures des méthodes correspondantes de la classe du bean.
  • Les arguments et valeurs de retour doivent être des types RMI valides.
  • La clause throws doit inclure java.rmi.RemoteException.

Classes utilitaires

Le bean de session CartEJB utilise 2 classes utilitaires: BookException et IdVerifier. La BookException est déclenchée par la méthode removeBook et IdVerifier valide le customerId dans l'une des méthodes ejbCreate. Les classes utilitaires doivent résider dans le fichier EJB JAR qui contient le bean d'entreprise.

Exercice

Sur la base de ces explications et des fragments de code construire une application qui utilise un bean de session semblable à EJBCart (sans les classes utilitaires) avec une servlets et des JSP comme contrôleur.