In
[SEJB] è stato presentato un esempio di Session EJB, sia stateless
che stateful.
Per
testare il Session Stateless bean Concat in [SEJB] è stato sviluppata
un’applicazione stand-alone client (ConcatClient.java) che, una volta localizzato
l’EJB, ne invocava il suo business method concat passando come parametri
due stringhe e ricevendo come risultato la loro concatenazione.
. . .
Context
initial = new InitialContext();
//Localizzazione
della Home interface mediante JNDI
Object
objRef = initial.lookup("MyService");
//PortableRemoteObject.narrow
effettua l'opportuno “CAST”
ConcatHome
home = (ConcatHome)
PortableRemoteObject.narrow(objRef,ConcatHome.class);
//creo
l'oggetto Remoto mediante il metodo
//create
della Home interface
Concat
remoteConcat = home.create();
//invocazione
del business method
String
res = remoteConcat.concat("Hello", " EJB World !");
.
. .
Se
il client viene eseguito sulla stessa macchina del Server si può
mandare in esecuzione il ConcatClient referenziando nel classpath il ConcatAppClient.jar
[SEJB] :
java
-classpath .;%J2EE_HOME%\lib\j2ee.jar;ConcatAppClient.jar ConcatClient
Se
il client invece è eseguito da una macchina remota, si possono scegliere
due strade per configurare opportunamente la macchina client :
-
1) Utilizzare
la proprietà org.omg.CORBA.ORBInitialHost referenziandola al Server
java
-classpath .;%J2EE_HOME%\lib\j2ee.jar;ConcatAppClient.jar -Dorg.omg.CORBA.ORBInitialHost=<SERVER>
ConcatClient
-
Specificare
il context factory (il protocollo) ed il service provider (il server
JNDI) dal quale recuperare la Home Interface.
Nel
caso dell’ Application Server Reference Implementation di SUN il
JNDI Server risponde sulla porta TCP 1050 ed utilizza il protocollo RMI-IIOP.
Questo
implica settare le proprietà java.naming.factory.initial e
java.naming.provider.url :
java
-classpath .;%J2EE_HOME%\lib\j2ee.jar;ConcatAppClient.jar
-Djava.naming.factory.initial=
com.sun.jndi.cosnaming.CNCtxFactory
-Djava.naming.provider.url=iiop://<SERVER>:1050
ConcatClient
In entrambi
i casi al posto di <SERVER> si deve specificare il nome o l’indirizzo
IP della macchina server ed il comando deve essere su un’unica riga.
|
Figura
1
Servlet
Sviluppando
il client come applicazione stand-alone bisogna distribuire il bytecode
del client ed il Jar su tutte le macchine degli utenti.
Tali
vincoli possono essere rimossi sviluppando una Servlet il cui compito
è di comunicare con l’EJB diventando lei stessa un Ejb client.
In
questo modo non si dovrà distribuire nessun software sulla macchina
client ponendo come unico vincolo l'avere un’Internet Browser
che comunichi con il Web Server.
La
Servlet permette quindi al client web browser di accedere indirettamente
all’EJB.
Il
Middletier dell’applicazione risulta essere costituito da due livelli
:
q
Livello di presentazione , costituito dal Servlet, che gestisce l'interfaccia
utente acquisendo i dati (le due stringhe da concatenare) e visualizzando
il risultato (la stringa concatenata)
q
Livello di business, che fornisce il servizio (la concatenazione
di due stringhe), implementato dall’EJB.
|
Figura
2
Per
invocare la Servlet si crea una pagina HTML, che mediante una form, inizializza
i parametri da inviare con una GET al web server.
Concat.html
<html>
<head>
<title>Concat</title>
</head>
<body>
<p>
<form
method = get action="ConcatServletAlias">
Inserisci
stringa :
<input
type=text name="firstString">
<p>
Inserisci
stringa :
<input
type=text name="secondString">
<p>
<input
type="submit" value="Inoltra">
</form>
<hr>
</body>
</html>
Concentrandoci
sul codice della ConcatServlet si vede come all’interno del metodo init
svolga le funzioni di EJB client ottenendo un reference alla remote
interface che inizializza la proprietà remoteConcat.
All’arrivo
della richiesta la servlet legge i parametri “firstString” e “secondString”
ed invoca il metodo di business :
String
concat(String, String).
Il
risultato della concatenazione viene formattato in HTML nel metodo generatePage.
ConcatServlet
import
java.io.*;
import
javax.servlet.*;
import
javax.servlet.http.*;
import
javax.rmi.PortableRemoteObject;
import
javax.naming.InitialContext;
import
javax.naming.Context;
import
Concat;
import
ConcatHome;
/**
* ConcatServelt : Servlet EJB client
*/
public
class ConcatServlet extends HttpServlet{
private
Concat remoteConcat = null;
public
void init()throws ServletException{
addItem("ConcatServlet.init : ...");
try {
Context initial = new InitialContext();
// Localizzazione della Home interface mediante JNDI
Object objRef = initial.lookup("MyService");
// utilizzo la classe PortableRemoteObject
// per effettuare l'opportuno “CAST”
ConcatHome home = (ConcatHome)PortableRemoteObject.narrow(
objRef,ConcatHome.class);
addItem("home = "+ home.getClass().getName());
// creo l'oggetto Remoto mediante il metodo
// create della Home interface
remoteConcat = home.create();
addItem("remote = "+
remoteConcat.getClass().getName());
}
catch (Exception ex){
addItem("# Excpetion ! ConcatServlet.init : "
+ ex.getMessage());
ex.printStackTrace();
}
}
public void doGet (HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException{
addItem("ConcatServlet.doGet : ...");
String firstString = req.getParameter("firstString");
String secondString = req.getParameter("secondString");
addItem("firstString["+firstString+"] -
secondString[" + secondString + "]");
// richiesta di concatenazione
String result = remoteConcat.concat(
firstString, secondString);
res.setContentType("text/html");
PrintWriter out = res.getWriter();
generatePage(out,result);
}
private
void generatePage(PrintWriter out, String result){
out.println("<html>");
out.println("<head>");
out.println("<title>Concat Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h2><b><center>Concat
Servlet</center></b></h2><hr>");
out.println("<h3><b>Risultato concatenazione : " + result +
"</h3></b><hr>");
out.println("<p>");
out.println("<form method = get
action=\"ConcatServletAlias\">");
out.println("Inserisci stringa : ");
out.println("<input type=text name=\"firstString\">");
out.println("<p>");
out.println("Inserisci stringa : ");
out.println("<input type=text name=\"secondString\">");
out.println("<p>");
out.println("<input type=submit value=\"Inoltra\">");
out.println("</form>");
out.println("<hr>");
out.println("</body>");
out.println("</html>");
}
/**
Log message to console */
private
void addItem(String s){
s = new java.util.Date().toString() + "-" + s;
System.out.println(s);
}
}
Installazione
della Servlet
Dopo
aver compilato la Servlet
javac
-classpath .;%J2EE_HOME%\lib\j2ee.jar;ConcatAppClient.jar ConcatServlet.java
si
può procedere ad installarla nell’Application Server.
Avviato
il deploytool (es: d:\j2sdjee1.2\bin\deploytool) si seleziona l’applicazione
ConcatApp (vedi [SEJB]) e dal Menu file si sceglie New Web component (fig.3).
|
Figura
3
Il
Web Component non è altro che un insieme di risorse Web (HTML, JSP,
Bean, Servlet) che viene installato sull’Application Server con un file
di estensione WAR, un termine un po’ “bellicoso” che indica un Web Archive.
Le
risorse contenute nel Web Component vengono gestite all’interno del Web
Container del J2EE Server così come gli EJB vengono gestiti da un
EJB Container.
|
Figura
4
Nella
prima finestra del Wizard si deve inserire il nome che si vuole assegnare
al Componente Web (es:ConcatServletWAR) nel campo DISPLAY NAME e premere
il tasto ADD per aggiungergli i file.
Si
inserisce come prima risorsa , mediante il bottone ADD, il file Concat.html
e si seleziona NEXT.
|
Figura
5
Successivamente
si inserisce il ConcatServlet.class e si preme FINISH
|
Figura
6
Il
Web Component di nome ConcatWAR risulta essere quindi formato dal ConcalServlet.class
e dal file Concat.html.
|
Figura
7
Alla
successiva finestra si esplicita il tipo di componente Web che si sta creando
che nel nostro caso è una Servlet.
|
Figura
8
Bisogna
poi assegnare un nome al componente Web (es:TheConcatServlet)
|
Figura
9
La
successiva videata permette, tramite il bottone ADD, di assegnare un'alias
URL alla Servlet (es:ConcatServletAlias) Si noti che questo è l'alias
referenziato nella pagina Concat.html.
|
Figura
10
Selezionando
il bottone FINISH si vede che all’Applicazione Concat
è stato aggiunto il Web Component ConcatWAR.
Prima
di procedere al deploy si deve assegnare al ConcatWAR il nome JNDI, che
nell'esempio è ConcatServletContextRoot.
|
Figura
11
A questo
punto si può procedere al deploy dell’Applicazione senza richiedere
di generare il file Jar per il client.
|
Figura
12
Mediante
NEXT si ha il riepilogo dei JNDI names sia per il Session Stateless Bean
(MyService), che per la Servlet (ConcatServletContextRoot).
Schiacciando
FINISH compare la finestra relativa al deploy.
|
Figura
13
E'
possibile accedere alla pagina Concat.html mediante l'URL
http://<SERVER>:8000/ConcatServletContextRoot/Concat.html
e dopo
avere inserito le due stringhe da concatenare viene invocata la Concatservlet.
La
figura 14 mostra il risulato che la Servlet fornisce in seguito alla richiesta
di concatenazione tra le stringhe "Hello" e " EJB World !".
http://myserver:8000/ConcatServletContextRoot/ConcatServletAlias
?firstString=Hello&secondString=EJB World !
|
Figura
14
Java Server Pages
Le
Servlet presentano la scomodità di avere cablato nel codice la struttura
della pagina HTMl da visualizzare all’utente.
In
questo modo se si ha la necessità di modificare la parte HTML bisogna
necessariamente modificare il codice Java e ricompilare il tutto.
La
naturale evoluzione delle Servlet sono le pagine JSP, che permettono
una netta distinzione tra codice HTML e codice Java.
In
un Web Component si può inserire anche una pagina JSP e di conseguenza
sfruttarne i vantaggi intrinseci.
Nella
versione JSP1.1 non è possibile invocare un’Ejb direttamente da
una pagina JSP mediante l'utilizzo delle action standard JSP (jsp:useBean,
jsp:getProperty e jsp:setProperty) , ma bisogna utilizzare o script o usare
la mediazione di un worker bean.
Vediamo
come invocare il nostro EJB da pagina JSP mediante un bean che fondamentalmente
effettua le funzioni di Proxy verso l’EJB.
La
pagina Concat.jsp utilizza un bean di classe ConcatProxyBean ottenendo
la concatenazione delle proprietà firstString e secondString mediante
l’invocazione del metodo processRequest.
|
Figura
15
Concat.jsp
<html>
<jsp:useBean
id="proxyBean" scope="session" class="ConcatProxyBean" />
<jsp:setProperty
name="proxyBean" property="*" />
<%!
String result; %>
<%
result = proxyBean.processRequest(); %>
<html>
<head>
<title>Concat JSP</title>
</head>
<h1><b><center>Concat
JSP</center></b></h1>
<hr>
<form
method=POST action=Concat.jsp>
<p>Inserisci
stringa : <INPUT type=text name="firstString" size="8" value="<jsp:getProperty
name="proxyBean" property="firstString" />" >
<p>Inserisci
stringa : <INPUT type=text name="secondString" size="8" value="<jsp:getProperty
name="proxyBean" property="secondString" />">
<p><INPUT
type=submit name="submit" value="Submit">
</form>
<hr>
<h3><b>Risultato
concatenazione : <%= result %> </h3></b>
<hr>
</body>
</html>
ConcatProxyBean
Il
ConcatProxyBean ottiene un reference alla remote interface nel costruttore
ed invoca il metodo concat dell’EJB all’interno del metodo processRequest.
/**
ConcatProxyBean.java */
import
java.util.*;
import
java.io.*;
import
javax.naming.Context;
import
javax.naming.InitialContext;
import
javax.rmi.PortableRemoteObject;
public
class ConcatProxyBean {
private
String firstString;
private
String secondString;
private
ConcatHome home = null;
public
ConcatProxyBean(){
addItem("ConcatProxyBean : costruttore ...");
try {
Context ic = new InitialContext();
java.lang.Object objref = ic.lookup("MyService");
home = (ConcatHome) PortableRemoteObject.narrow(objref,
ConcatHome.class);
addItem("home = "+ home.getClass().getName());
}
catch (Exception e){
addItem(" # Exception ! concatHome non localizzata : " +
e.getMessage());
e.printStackTrace();
}
}
public
String processRequest() {
Concat concat = null;
String result = "";
addItem("processRequest : this["+this+"]");
try {
if((this.firstString != null) && (this.secondString != null)){
addItem("ConcatProxyBean.processRequest:"+
this.firstString+"-"+this.secondString);
// creo l'oggetto Remoto mediante il metodo
// create della Home interface
Concat remoteConcat = home.create();
addItem("remote = "+ remoteConcat.getClass().getName());
result = remoteConcat.concat(firstString, secondString);
addItem("Result = " + result);
}
}
catch
(Exception e){
result = e.toString();
}
return
result;
}
public
String getFirstString() {
return firstString;
}
public
void setFirstString(String value) {
this.firstString = value;
}
public
String getSecondString() {
return firstString;
}
public
void setSecondString(String value) {
this.secondString = value;
}
/**
Log message to console */
private
void addItem(String s){
s = new java.util.Date().toString() + "-" + s;
System.out.println(s);
}
}
Installazione
della pagina JSP
Avviato
il deploytool si seleziona l’applicazione ConcatApp e dal menu
File la voce New Web Component, come visto precedentemente per la Servlet.
Mediante
il bottone ADD si inseriscono il file Concat.jsp e ConcatProxyBean.class.
|
Figura
16
Alla
successiva finestra si esplicita il tipo di componente Web che si sta creando,
che nel nostro caso è una JSP.
|
Figura
17
In
seguito si deve assegnare un nome al Componente e un'URL alias. Nell'esempio
proposto come URL alias si è usato ConcatJspAlias.
Selezionando
FINISH si vede che all’Applicazione Concat è stato aggiunto
il Web component ConcatJspWAR
Prima
di procedere al deploy bisogna assegnare al ConcatWAR il nome JNDI, che
nell'esempio è ConcatJspContextRoot.
|
Figura
18
A questo
punto si può procedere al deploy dell’Applicazione nel solito modo.
Per
invocare la pagina JSP dal web browser basta inserire il seguente URL :
http://<SERVER>:8000/ConcatJspContextRoot/Concat.jsp
Il
risultato di una semplice concatenazione è mostrato in figura 19.
|
Figura
19
Bibliografia
[SEJB]
S.Rossini - "Session EJB : un esempio applicativo", Mokabyte N46,
Novembre 2000
[EJBA]
A.Giovannini, R.Spazzoli - Rassegna di application server EJB, Mokabyte
N.44, Settembre 2000
[J2EE]
J2SDKEE1.2 Documentation
|