Académique Documents
Professionnel Documents
Culture Documents
JAVA EE
getPlaces() getTrips()
Clients
Session Bean : Stateless (sans état)
9
getPlaces() getTrips()
Clients
Session Bean : Singleton
12
¨ Les clients accèdent aux beans entreprise via une interface métier.
¨ Une interface métier est une interface Java standard contenant les méthodes
métier du bean enterprise.
¨ Un client peut accéder à un session
bean uniquement via les méthodes
définies dans l'interface métier du
bean ou via les méthodes publiques
d'un bean d'entreprise ne disposant Interface
d'aucune vue.
Desktop application
¨ L’interface métier définit la vue du
client d’un bean entreprise. Tous les
autres aspects du bean enterprise
(implémentations de méthodes et Interface
paramètres de déploiement) sont
masqués au client. Implementation
¤ Les clients n'utilisent pas l'opérateur new pour obtenir une nouvelle
instance d'un bean enterprise utilisant une vue sans interface.
Accéder aux Enterprise Beans :
Client Local
25
¤ Pour obtenir une référence à une interface métier locale d'un bean
d'entreprise via la recherche JNDI, on utilise la méthode de
recherche de l'interface javax.naming.InitialContext:
ExampleLocal example = (ExampleLocal) InitialContext.lookup("java:module/ExampleLocal");
Accéder aux Enterprise Beans :
Client distant
26
¨ Les beans Enterprise étant composés de plusieurs parties, il est utile de suivre
une convention de dénomination pour les applications.
Elément Syntaxe Exemple
Enterprise bean name nameBean accountBean
Enterprise bean class NameBean AccountBean
Business interface Name Account
Cycle de vie des beans entreprise
35
¨ Etant donné qu'un bean de session sans état n'est jamais passivé, son cycle de
vie n'a que deux étapes:
¤ Inexistant;
¤ Prêt pour l'invocation de méthodes métier.
¨ Le conteneur EJB crée et gère généralement un pool de beans de session
sans état, en commençant le cycle de vie du bean de session.
¨ Le conteneur effectue toute injection de dépendance, puis appelle la
méthode annotée @PostConstruct, si elle existe.
¨ Le bean est maintenant prêt à avoir ses méthodes métier appelées par un
client.
¨ À la fin du cycle de vie, le conteneur EJB appelle la méthode annotée
@PreDestroy, si elle existe. L’instance du bean est alors prête pour la
récupération par le garbage collector.
Cycle de vie: Singleton Session Bean
39
¨ Le bean enterprise dans l’exemple est un bean de session sans état appelé
ConverterBean.
¨ Cette classe implémente deux méthodes métier: dhToDollar et dhToEuro.
¨ Étant donné que la classe de bean enterprise n'implémente pas d'interface
métier, le Bean entreprise expose une vue locale sans interface.
¨ Les méthodes publiques de la classe de beans enterprise sont disponibles
pour les clients qui obtiennent une référence à ConverterBean.
¨ Le code source de la classe ConverterBean est le suivant:
import java.math.BigDecimal;
import javax.ejb.*;
@Stateless
public class ConverterBean {
private BigDecimal dollarRate = new BigDecimal("0.11");
private BigDecimal euroRate = new BigDecimal("0.092");
@EJB
ConverterBean converter;
…..
Créer le client Web du bean
entreprise
45
import exemplejavaee.converter.ejb.ConverterBean;
import java.io.*;
import java.math.BigDecimal;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(urlPatterns = "/")
public class ConverterServlet extends HttpServlet {
private static final long serialVersionUID = 7L;
@EJB
ConverterBean converter;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// Output the results
out.println("<html lang=\"en\">");
out.println("<head>");
out.println("<title>Servlet ConverterServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet ConverterServlet at " + request.getContextPath() + "</h1>");
try {
String amount = request.getParameter("amount");
if (amount != null && amount.length() > 0) {
// convert the amount to a BigDecimal from the request parameter
BigDecimal d = new BigDecimal(amount);
// call the ConverterBean.dhToDollar() method to get the amount in Dollar
BigDecimal dollarAmount = converter.dollarToDh(d);
// call the ConverterBean.dhToEuro() method to get the amount in Euro
BigDecimal euroAmount = converter.dhToEuro(d);
out.println("<p>" + amount + " dirhams are " + dollarAmount.toPlainString() + " Dollars.</p>");
out.println("<p>" + amount + " dirhams are " + euroAmount.toPlainString() + " Euro.</p>");
Créer le client Web du bean
entreprise
46
} else {
out.println("<p>Enter a dirham amount to convert:</p>");
out.println("<form method=\"get\">");
out.println("<p><input title=\"Amount\" type=\"text\" name=\"amount\" size=\"25\">Dhs</p>");
out.println("<br/>");
out.println("<input type=\"submit\" value=\"Submit\">" + "<input type=\"reset\"
value=\"Reset\">");
out.println("</form>");
}
} finally {
out.println("</body>");
out.println("</html>");
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
Bean de session avec état
47
¨ L'interface métier Cart est une interface Java simple qui définit toutes les
méthodes métiers implémentées dans la classe de bean.
¨ Si la classe de bean implémente une interface unique, cette interface est
supposée être l'interface métier.
¨ L'interface métier est une interface locale sauf si elle est annotée avec
l'annotation javax.ejb.Remote; l'annotation javax.ejb.Local est facultative
dans ce cas.
¨ La classe de bean peut implémenter plusieurs interfaces.
¨ Dans ce cas, les interfaces métier doivent être explicitement annotées @Local
ou @Remote ou spécifiées en décorant la classe de bean avec @Local ou
@Remote.
¨ Cependant, les interfaces suivantes sont exclues pour déterminer si la classe
de bean implémente plusieurs interfaces (on ne doit pas les compter):
¤ java.io.Serializable
¤ java.io.Externalizable
¤ N'importe laquelle des interfaces définies par le package javax.ejb
Bean de session avec état
49
@Remote
public interface Cart {
public void initialize(String person) throws BookException;
¨ Dans cet exemple, Le bean de session avec état CartBean est une
classe Java simple qui implémente toutes les méthodes métiers de
l'interface métier Cart .
¨ Comme tout bean de session avec état, la classe CartBean doit
répondre aux exigences suivantes.
¤ La classe est annotée @Stateful.
¤ La classe implémente les méthodes métier définies dans l'interface métier.
¨ Les beans de session avec état peuvent également effectuer les
opérations suivantes:
¤ Implémenter l'interface métier du bean.
¤ Implémenter toutes les méthodes facultatives de cycle de vie, annotées
@PostConstruct, @PreDestroy, @PostActivate et @PrePassivate.
¤ Implémenter toutes les méthodes métier facultatives annotées @Remove.
Bean de session avec état
51
//Classe BookException.java
package exemplejavaee.cart.utils;
public class BookException extends Exception {
private static final long serialVersionUID = 6274585742564840905L;
public BookException() {
}
public BookException(String msg) {
super(msg);
}
}
//Classe IdVerifier.java
package exemplejavaee.cart.utils;
¨ Méthodes métiers
¨ L'objectif principal d'un bean session est d'exécuter des
tâches métier pour le client.
¨ Le client appelle des méthodes métier sur la référence
d'objet obtenue à partir d'une injection de dépendance ou
d'une recherche JNDI.
¨ Du point de vue du client, les méthodes métier semblent
s’exécuter localement, bien qu’elles s’exécutent à distance
dans le bean session.
Bean de session avec état
58
¨ La méthode @Remove
¤ Les méthodes métier annotées avec javax.ejb.Remove dans la classe de
bean de session avec état peuvent être appelées par les clients de bean
enterprise pour supprimer l'instance de bean.
¤ Le conteneur supprimera le bean enterprise après qu'une méthode
@Remove se termine normalement ou anormalement.
¨ Classes auxiliaires (Helper)
¤ Le bean session CartBean a deux classes auxiliaires:
n BookException : L’exception BookException est levée par la méthode removeBook
n IdVerifier : La classe IdVerifier valide le customerId dans l'une des méthodes
de création.
¤ Les classes auxiliaires peuvent résider dans un fichier JAR EJB contenant la
classe de bean entreprise; un fichier WAR si le bean enterprise est intégré à
un WAR; ou un fichier EAR contenant un fichier EJB JAR, un fichier WAR ou un
fichier JAR de bibliothèque séparé.
¤ Dans le panier, les classes auxiliaires sont incluses dans un fichier JAR de
bibliothèque utilisé par le client d'application et le fichier JAR EJB.
Bean de Session Singleton
60
@PostConstruct
void init{
status = "Ready";
}
...
}
¤ Parfois, plusieurs beans singleton sont utilisés pour initialiser les données d'une application
et doivent donc être initialisés dans un ordre spécifique.
¤ Dans ces cas, on utilise l'annotation javax.ejb.DependsOn pour déclarer les dépendances
de démarrage du bean de session singleton.
¤ L’attribut value de l’annotation @DependsOn est constitué d’une ou de plusieurs chaînes
spécifiant le nom du bean de session singleton cible.
¤ Si plus d'un bean singleton dépendant est spécifié dans @DependsOn, l'ordre dans lequel
ils sont répertoriés n'est pas nécessairement l'ordre dans lequel le conteneur EJB initialisera
les beans de session singleton cibles.
Bean de Session Singleton
63
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@Singleton
public class AnotherSingletonBean { ... }
Bean de Session Singleton
71
package exemplejavaee.counter.web;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Named;
import exemplejavaee.counter.ejb.CounterBean;
@Named
@ConversationScoped
public class Count implements Serializable {
@EJB
private CounterBean counterBean;
private int hitCount;
public Count() {
this.hitCount = 0;
}
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
/**
* HelloServiceBean is a web service endpoint implemented as a stateless session bean.
*/
@Stateless
@WebService
public class HelloServiceBean {
private final String message = "Hello, ";
@WebMethod
public String sayHello(String name) {
return message + name + ".";
}
}
Web Service
82
@Timeout
public void timeout(Timer timer) {
System.out.println("TimerBean: timeout occurred");
}
Timer Service
90
@Schedules ({
@Schedule(dayOfMonth="Last"),
@Schedule(dayOfWeek="Fri", hour="23")
})
public void doPeriodicCleanup() { ... }
Timer Service
96
¤ Pour récupérer tous les timers actifs d’un bean, appeler la méthode
getTimers de l’interface TimerService. La méthode getTimers
renvoie une collection d'objets Timer.
Timer Service
99
¨ Timersession Exemple
¤ TimerSessionBean est un bean de session singleton qui montre comment
définir à la fois un timer automatique et un timer programmatique.
¤ Dans le code source de TimerSessionBean qui suit, les méthodes setTimer
et @Timeout sont utilisées pour définir un timer programmatique.
¤ Une instance de TimerService est injectée par le conteneur lors de la
création du bean. Comme il s’agit d’une méthode métier, setTimer est
exposé à la vue locale, sans interface, de TimerSessionBean et peut être
appelé par le client.
¤ Dans cet exemple, le client appelle setTimer avec une durée d'intervalle
de 8 000 millisecondes ou 8 secondes. La méthode setTimer crée un
nouveau minuteur en appelant la méthode createTimer de TimerService.
¤ Maintenant que le timer est défini, le conteneur EJB appellera la méthode
programmaticTimeout de TimerSessionBean à l'expiration du minuteur,
dans environ 8 secondes .
Timer Service
100
¨ Timersession Exemple
¤ TimerSessionBean a également une méthode de minuterie et de
délai automatique, automaticTimeout.
¤ Le Timer automatique est configuré pour expirer toutes les
minutes et est défini à l'aide d'une expression de timer basée
sur un calendrier dans l'annotation @Schedule .
¤ TimerSessionBean a également deux méthodes métier:
getLastProgrammaticTimeout et getLastAutomaticTimeout.
¤ Les clients appellent ces méthodes pour obtenir la date et
l'heure du dernier délai d'expiration respectivement pour le
timer programmatique et le timer automatique.
¤ Voici le code source de la classe TimerSessionBean:
Timer Service : Timersession
Exemple
101
package exemplejavaee.timersession.ejb;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
/**
* TimerBean is a singleton session bean that creates a timer and prints out a
* message when a timeout occurs.
*/
@Singleton
@Startup
public class TimerSessionBean {
@Resource
TimerService timerService;
private Date lastProgrammaticTimeout;
private Date lastAutomaticTimeout;
@Timeout
public void programmaticTimeout(Timer timer) {
this.setLastProgrammaticTimeout(new Date());
logger.info("Programmatic timeout occurred.");
}
/**
* @return the lastTimeout
*/
public String getLastProgrammaticTimeout() {
if (lastProgrammaticTimeout != null) {
return lastProgrammaticTimeout.toString();
} else {
return "never";
}
}
Timer Service : Timersession
Exemple
103
/**
* @param lastTimeout the lastTimeout to set
*/
public void setLastProgrammaticTimeout(Date lastTimeout) {
this.lastProgrammaticTimeout = lastTimeout;
}
/**
* @return the lastAutomaticTimeout
*/
public String getLastAutomaticTimeout() {
if (lastAutomaticTimeout != null) {
return lastAutomaticTimeout.toString();
} else {
return "never";
}
}
/**
* @param lastAutomaticTimeout the lastAutomaticTimeout to set
*/
public void setLastAutomaticTimeout(Date lastAutomaticTimeout) {
this.lastAutomaticTimeout = lastAutomaticTimeout;
}
}
Timer Service : Timersession
Exemple
104
package exemplejavaee.timersession.web;
import java.io.Serializable;
import exemplejavaee.timersession.ejb.TimerSessionBean;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named
@SessionScoped
public class TimerManager implements Serializable {
@EJB
private TimerSessionBean timerSession;
private String lastProgrammaticTimeout;
private String lastAutomaticTimeout;
¨ Timersession Exemple
¤ Déployer et exécuter le projet
¤ Cliquer sur Définir la minuterie pour
définir une minuterie programmatique.
¤ Attendre un moment et cliquer sur le
bouton Actualiser du navigateur. La
date et l'heure des derniers délais
d'expiration programmatique et
automatique sera afficher.
¤ Pour voir les messages consignés lors
d'un dépassement de délai, ouvrir le
fichier server.log situé dans le
répertoire domain/logs/ .
Gestion des exceptions
108
@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
...
if (SessionContext.wasCancelled()) {
// clean up
} else {
// process the payment
}
...
}
Invocation de méthode asynchrone
114
import java.text.DateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;
import javax.inject.Named;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
@Named
@Stateless
public class MailerBean {
@Resource(name = "mail/myExampleSession")
private Session session;
private static final Logger logger = Logger.getLogger(MailerBean.class.getName());
@Asynchronous
public Future<String> sendMessage(String email) {
String status;
Invocation de méthode asynchrone :
Exemple
119
try {
Properties properties = new Properties();
properties.put("mail.smtp.port", "3025");
session = Session.getInstance(properties);
Message message = new MimeMessage(session);
message.setFrom();
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email,
false));
message.setSubject("Test message from asynchrone example");
message.setHeader("X-Mailer", "JavaMail");
DateFormat dateFormatter = DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat. LONG);
Date timeStamp = new Date();
String messageBody = "This is a test message from the asynchrone "
+ "example of the Java EE. It was sent on " + dateFormatter.format(timeStamp) +
".";
message.setText(messageBody);
message.setSentDate(timeStamp);
Transport.send(message);
status = "Sent";
logger.log(Level.INFO, "Mail sent to {0}", email);
} catch (MessagingException ex) {
logger.severe("Error in sending message.");
status = "Encountered an error: " + ex.getMessage();
logger.severe(ex.getMessage());
}
return new AsyncResult<>(status);
}
}
Invocation de méthode asynchrone :
Exemple
120
package exemplejavaee.async.web;
import java.io.Serializable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Logger;
import exemplejavaee.async.ejb.MailerBean;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named
@SessionScoped
public class MailerManagedBean implements Serializable {
private static final long serialVersionUID = 1L;
@EJB
protected MailerBean mailerBean;
protected String email;
protected String status;
private Future<String> mailStatus;
public MailerManagedBean() {
}
Invocation de méthode asynchrone :
Exemple
121
public String getStatus() {
if (mailStatus.isDone()) {
try {
this.setStatus(mailStatus.get());
} catch (ExecutionException | CancellationException | InterruptedException ex) {
this.setStatus(ex.getCause().toString());
}
}
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String send() {
try {
mailStatus = mailerBean.sendMessage(this.getEmail());
this.setStatus("Processing... (refresh to check again)");
} catch (Exception ex) {
logger.severe(ex.getMessage());
}
return "response?faces-redirect=true";
}
}
Invocation de méthode asynchrone :
Exemple
122
package exemplejavaee.async.smtp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
out.println("220 exemplejavaee.asyncsmtp");
inline = in.readLine();
if (inline.split(" ")[0].compareTo("HELO") != 0 &&
inline.split(" ")[0].compareTo("EHLO") != 0) {
client.close(); return;
}