Introduzione
I portali stanno diventando i principali mezzi di integrazione
di informazioni e applicazioni disponibili nelle intranet
e in Internet. Chiunque cerchi oggi di sviluppare un
sito Web, lo fa usando una sorta di tecnologia tipica
dei portali. Se vogliamo infatti scoprire il perché
questa tecnologia sia ormai così popolare, dobbiamo
per esempio osservare al come si è evoluti dai
tempi dell' MS-DOS, in cui, per passare da un'applicazione
all'altra, bisognava prima chiuderne una per poi fare
partire la seconda, ai tempi di Windows, in cui si è
in grado di associare ad ogni applicazione una sua finestra.
Da questo ragionamento nasce il concetto di "aggregazione
di applicazioni", che diventerà la funzione
primaria di un portal server.
Analogamente, dal momento che i servizi Web stanno diventando
il metodo predominante per rendere le informazioni e
le applicazioni disponibili via Internet, molto presto
i portali avranno la necessità di permettere
l'integrazione dei Web Services come fonti di dati e
come componenti applicativi remoti.
Per aggregare e visualizzare dinamicamente contenuti
diversi, un portal server dovrà fornire una struttura
che sia in grado di inserire i contenuti del portale
in opportuni moduli, quali possono essere i Portlets.
Ciascun
portlet sarà responsabile nel fornire specifiche
informazioni e servizi, dovrà svolgere compiti
di controllo di accesso al suo contenuto ( come per
esempio da un sito Web, da un database o da un Web service
) e quindi trasformare e modellare il contenuto stesso
cosicché questo possa essere efficientemente
reso al client.
Tipicamente, i portlets girano sul portal server, elaborando
i dati in ingresso e visualizzandone i risultati. I
dati richiamati dal portlet sono solitamente locali,
ma potrebbero anche essere remoti, facendo per esempio
uso di Web services.
Un tipico esempio può essere quello di un News
Portlet che permette all'utente di scegliere le categorie
di notizie da seguire, aggiornandole in tempo reale
direttamente dai Web Services corrispondenti.
Normalmente la presentazione delle notizie viene svolta
dal portlet locale, mentre il Web Service fornisce soltanto
le informazioni grezze nella forma di un documento XML,
ma, come vedremo, una possibile via di sviluppo può
prevedere anche l'utilizzo di Web services remoti nelle
vesti di portlets remoti, in grado di contenere sia
una logica applicativa che una logica di presentazione.
In tal caso si parla di Remote Portlet Web Services.
Da un punto di vista lato-user, un portlet si presenta
come una "piccola" finestra all'interno della
pagina del portale, a cui è quindi associato
uno specifico servizio o delle informazioni ( es. itinerari
di viaggio, news, servizi meteo, informazioni sportive
o pubblicitarie ). L'utente potrà personalizzare
il contenuto, la struttura e la posizione del portlet
secondo le preferenze di profilo settate dall'amministratore
a cui il portlet appartiene.
Da un punto di vista applicativo lato-server, un portlet
è invece un modulo disegnato per girare all'interno
di un portlet container; in altre parole è una
componente implementata come una JSP che definisce un
contenuto statico e dinamico per un soggetto specifico
(meteo, news, ecc.) nella pagina del portale.
Portlet
e Web services
Ci sono due opzioni importanti per integrare i servizi
Web all'interno di un portale che fa uso di portlets,
il tradizionale data-oriented Web service ed il presentation-oriented
and interactive Web service.
- La
prima opzione prevede che i portlet siano posti su
un Portal Server in grado di accedere ai servizi Web
per ottenere informazioni o attivarne le procedure
previste. In pratica è una infrastruttura secondo
la quale ad ogni portlet è associato un servizio
presente su un Web service remoto
Figura 1 - Esempio di portale con portlets che richiamano
Web Services
In
questo caso si fa anche uso di cache locali al portal
server per effettuare refresh più frequenti
del contenuto dei portlets.
I data-oriented Web services ricevono richieste SOAP
e forniscono come risposta dati codificati in documenti
Xml, sempre secondo lo standard SOAP. Sarà
poi dovere del service consumer elaborare i dati ricevuti
nella maniera corretta ed offrire quindi il proprio
servizio. Tali Web Services non si occupano però
di presentare i risultati, ma solo di restituirli
come risposta.
Lo svantaggio di questo genere di Web Services si
presenta quando un portale necessita di integrare
velocemente contenuti e applicazioni da sorgenti differenti
e diverse tra loro.
E' quindi immediato comprendere come questa opzione
venga usata in particolar modo in quei casi in cui
è necessario avere dei buoni tempi di risposta
del servizio.
- La
seconda opzione prevede invece che i portali possano
pubblicare i portlet essendo questi in realtà
dei servizi remoti.
Figura 2 - Esempio di portale che usa Remote Portlet
Web Services
In
questo caso i Web Services si presentano in realtà
come dei Remote Portlet Web Services che, a differenza
della prima opzione, contengono una logica sia di presentazione
che di applicazione. Invece cioè di fornire solo
dati grezzi o funzioni varie che richiedono poi un rendering
da parte del portale, i portlet remoti sono in sostanza
dei Web Services visuali, che si presentano semplicemente
come delle applicazioni web aggregabili che possono
quindi essere invocate attraverso una interfaccia standard
di portlet proxy dalla parte del portale.
In altre parole gli user-facing Web services includono
anche la presentazione come parte del servizio stesso.
Essi non restituiscono dati che devono poi essere elaborati
e girati in una presentazione dal consumatore, ma invece
producono frammenti di markup facilmente aggregabili
dal portale.
In
ogni caso, ciascun portlet sarà responsabile
di fornire specifiche informazioni e servizi, dovrà
svolgere determinati compiti e quindi trasformare e
modellare il contenuto stesso così che questo
possa essere efficientemente reso al client nella forma
a lui più adeguata.
Un buon portale dovrà comunque essere in grado
di :
- supportare
portlets locali
- includere
portlets remoti
- condividere
portlets locali rendendoli disponibili ad altri portali
come Remote Portlet Web Services
Portlets
e Servlets
I portlets possono essere considerati come dei tipi
speciali di servlets, con proprietà che permettono
loro di inserirsi e girare facilmente sui portal server.
I portlets hanno altre varie caratteristiche, così
come però anche alcune restrizioni. Non come
le servlets, i portlets non possono mandare reindirizzamenti
o errori direttamente al browser, inoltrare richieste
o scrivere arbitrariamente markup al flusso di output.
Generalmente, i portlets sono amministrati più
dinamicamente delle servlets.
Il portlet container si affida ad una architettura J2EE,
implementata per esempio da IBM WebSphere Application
Server.
In questo modo, gli sviluppatori di portlet traggono
beneficio proprio perché:
- le
Portlet API riusano le ben note Servlet API, estendendole
quando necessario
- gli
sviluppatori che conoscono le Servlet API possono
immediatamente scrivere portlets
- gli
sviluppatori possono usare tools esistenti per sviluppare
portlets e componenti JSP, facendo sempre uso di tecnologie
J2EE
I
portlets sono impacchettati in file WAR come applicazioni
web J2EE e sono quindi presentati come servlets. Così
come una servlet, un portlet viene definito alla applicazione
server tramite un descrittore di applicazione web Xml
(web.xml ) che definisce la classe portlet, la servlet
mapping e i parametri di inizializzazione. A differenza
del descrittore delle servlets, i portlets devono però
anche fornire un descrittore portlet in grado di specificare
la proprie capacità al portal server, quali parametri
di configurazione di un particolare portlet o portletApplication
o comunque informazioni generali appartenenti a tutti
i portlets, come per esempio il tipo di markup che esso
supporta.
Il portal server userà quindi queste informazioni
per fornire i servizi per il portlet. Per esempio, se
viene associato al portlet un supporto di aiuto o di
edit mode nel descrittore Xml, allora il portal server
fornirà le icone per permettere l'accesso alle
pagine di help o di edit all'utente.
Architettura
del portal server
Una delle possibili soluzioni per lo sviluppo di un
portale web di servizi fa uso della piattaforma IBM
WebSphere Portal Server, con l'ausilio della tecnologia
delle Portlet Applications, secondo la quale, come già
detto, ad ogni componente Portlet viene associato un
servizio.
Per
realizzare un sistema in grado di rispondere alle specifiche
tipiche di un portale, è necessario disporre
di una architettura completa e flessibile nella quale
vengono definiti gli elementi base dell'infrastruttura
così come le interfacce ed i protocolli che li
pongono in relazione fra loro. Tale architettura dovrà
coprire tutto il percorso dai dispositivi di Front End
del client, attraverso portali e portlet locali o remoti,
fino ai Web services. Deve inoltre comprendere i meccanismi
ed i formati sia per introdurre il codice dei portlets
localmente nei portali e sia per trovare e agganciarsi
ai Web Services remoti.
La
figura qui sotto mostra una possibile architettura di
portale implementato con WebSphere:
Figura 3 - Architettura del Portal Server
(clicca per ingrandire l'immagine)
I
clients accedono al portale attraverso il protocollo
HTTP, sia direttamente che attraverso appositi Proxy
o Gateway come quelli WAP o vocali. I linguaggi di mark-up
usati da questi dispositivi possono essere molto diversi;
ad esempio, i telefoni WAP usano normalmente WML, i
telefoni iMode usano cHTML , i Browser vocali usano
di solito VoiceXML, mentre il più noto Web Browser
dei PC usa HTML.
Per soddisfare le esigenze di tutti questi dispositivi,
i portali devono quindi supportare i vari linguaggi
di mark-up.
Quando le pagine vengono aggregate per creare le videate
del portale, quest' ultimo richiama tutti i portlets
che appartengono a quella determinata pagina attraverso
le Portlet API.
I
portlets, così come avviene, sotto certi aspetti,
con le servlets, vengono inseriti in modo analogo all'interno
di portlet container che fanno sempre parte del portale.
I portlets sono dotati di API simili a quelle delle
servlets, ma, a differenza di queste ultime che funzionano
in un servlet container autonomo, in questo caso funzionano
in un ambiente portale. Inoltre, mentre le servlets
comunicano direttamente con i loro client, i portlets
vengono richiamati indirettamente attraverso le applicazioni
del portale.
Per
funzionare correttamente nel contesto di un portale,
i portlets devono produrre contenuti adatti ad essere
aggregati in pagine più grandi e per fare ciò
vuol dire che essi dovrebbero produrre porzioni di linguaggio
mark-up conformi alle linee guida di riferimento così
da assicurare contenuti sempre aggregabili tra loro.
Ritornando
alla descrizione dell'architettura, quando un portale
riceve una richiesta servlets, genera una portlet request
ed invia, tramite il dispatcher, gli eventi associati
a tutti i portlets implicati nell'operazione e successivamente
ne attiva il funzionamento preparandosi a riceverne
i risultati.
Un modello che si è dimostrato molto adatto alla
programmazione del portlet è quello basato sui
pattern Model-View-Controller ( MVC ).
Esso ripartisce le varie funzionalità del portlet
in un Controller che riceve le richieste in entrata,
attivando dei comandi che funzionano all'interno di
un modello Model che incapsula i dati e la logica dell'applicazione
ed infine richiama le viste View per la presentazione
dei risultati.
I portlets hanno inoltre accesso alle funzioni relative
ai portali ed ai dati attraverso le interfacce dei Portlet
Service ( Portlet API ). Queste interfacce forniscono
al portlet le funzioni che comprendono l'accesso alle
informazioni dell'infrastruttura del portale, del profilo
dell'utente, ai dati specifici dell'azione o allo stato
del portale.
Oltre a queste funzioni ,specifiche dei portali, i portlets
possono anche usare tutti i servizi J2EE che sono disponibili
alle servlets per poter accedere ai dati di Back-End,
alle applicazioni locali o persino ai servizi Internet.
Per accedere ai database ed effettuare tutte le operazioni
tipiche di un DataBase Management System vengono utilizzate
le JDBC API.
Ogni portlet prevede inoltre un suo descrittore web
( portlet.xml ), utile per contenere informazioni sull'applicazione,
sul suo identificativo, sul suo nome, opzioni di visualizzazioni,
etc.
Per facilitarne l'impiego, i portlets possono essere
raggruppati in Portlet Applications, inserite a loro
volta in Portlet File Archives che contengono i file
descrittori, le classi Java, i file jar e tutte le risorse
implicate nel loro funzionamento.
Creare
un proprio Portlet e Web service
Viene qui di seguito mostrato un semplice esempio di
portlet che visualizza le ore ed i minuti restanti nel
giorno ed è aggiornato ogni volta che viene effettuato
un refresh. La classe RemainingTimePortlet estende l'interfaccia
AbstractPortlet, utile per generare una nuova applicazione
di portlet. Così come le servlets, anche i portlets
presentano un metodo service che viene invocato dal
portale quando viene richiesto a tutti gli effetti il
contenuto del servizio.
package
esempio;
import java.io.*;
import java.util.*;
import org.apache.jetspeed.portlet.*;
import org.apache.jetspeed.portlets.*;
public class RemainingTimePortlet extends AbstractPortlet
{
public
void service(PortletRequest request, PortletResponse
response)
throws
PortletException, IOException {
// Calcola le ore ed i minuti
rimanenti.
Calendar calendar = Calendar.getInstance();
int hours = 24 - calendar.get(Calendar.HOUR_OF_DAY),
minutes = 0;
if (calendar.get(Calendar.MINUTE)
> 0) {
hours -= 1;
minutes = 60 - calendar.get(Calendar.MINUTE);
}
PrintWriter writer = response.getWriter();
writer.println("<p>Il
giorno terminerà tra " + hours +
" ore e " + minutes
+ " minuti.</p>");
}
}
Diamo
ora uno sguardo all'esempio precedente, usando il modello
MVC.
package
esempio;
import java.io.*;
import java.util.*;
import com.ibm.wps.portlets.*;
import org.apache.jetspeed.portlet.*;
import org.apache.jetspeed.portlets.*;
//
Classe Controller
public class RemainingTimeController extends AbstractPortletController
{
protected String jspHTML = "/WEB-INF/time/html/";
//
Metodo per inizializzare il portlet
public void init(PortletConfig config)
throws UnavailableException
{
super.init(config);
// Carica la JSP dalla configurazione
del Portlet
jspHTML += config.getInitParameter("view.HTML");
}
//
Metodo per rendere la vista del portlet
public void doView(PortletRequest request,
PortletResponse response)
throws PortletException, IOException
{
// Calcola le ore ed i minuti
rimanenti.
Calendar calendar = Calendar.getInstance();
int hours = 24 - calendar.get(Calendar.HOUR_OF_DAY),
minutes = 0;
if (calendar.get(Calendar.MINUTE)
> 0) {
hours -= 1;
minutes = 60 - calendar.get(Calendar.MINUTE);
}
// Crea un bean per passare il tempo
rimanente alla View JSP
TimeBean timeBean = new TimeBean();
timeBean.setHours(hours);
timeBean.setMinutes(minutes);
// Inserisci il bean nella request
per la JSP da usare
request.setAttribute("timeBean",
timeBean);
// Richiama la View JSP per
visualizzarla
getPortletConfig().getContext().include(jspHTML,
request, response);
}
}
package
esempio;
import java.io.*;
//
Bean usato per passare dati alla View JSP
public class TimeBean implements Serializable {
// Ore rimanenti
private int hours = 0;
// Minuti rimanenti
private int minutes = 0;
// Setta le ore rimanenti
public void setHours(int hours) {
this.hours = hours;
}
// Prendi le rimanenti ore
public int getHours() {
return hours;
}
// Setta i minuti rimanenti
public void setMinutes(int minutes) {
this.minutes = minutes;
}
// Prendi I minuti rimanenti
public int getMinutes() {
return minutes;
}
}
<!--------------------------------------------------------------------------->
<!- DisplayRemainingTime.jsp ------------------------------------------------>
<!- View JSP usata per visualizzare i dati nel Portlet
del tempo rimanente -->
<!--------------------------------------------------------------------------->
<%@ page contentType="text/html" errorPage=""
%>
<jsp:useBean id="timeBean"
class="com.ibm.wps.sample.time.TimeBean"
scope="request"/>
<p>Il giorno finirà tra <%= timeBean.getHours()
%> ore e
<%= timeBean.getMinutes() %> minuti.</p>
La prima cosa da notare in questo esempio è che
la prima classe non estende più la classe AbstractPortlet,
ma la classe AbstractPortletController che fornisce
una astrazione di un controllore per portlet. Questo
oggetto definisce comunque gli stessi metodi di setup
come la classe AbstractPortlet: init, login, logout
e destroy.
Occorre notare che la classe non ridefinisce più
direttamente il metodo service, ma invece ridefinisce
un metodo associato con una particolare modalità
portlet.
I portlets hanno infatti quattro modalità principali
di operazione:
- Portlet.Mode.VIEW
-
Portlet.Mode.EDIT
- Portlet.Mode.HELP
- Portlet.Mode.CONFIGURE
In
pratica, l'operazione viene suggerita proprio dal nome
della modalità corrispondente. Per ciascuna di
queste modalità la classe AbstractPortletController
ne fornisce un metodo: doView, doEdit, doHelp e doConfigure.
Ora
diamo un'occhiata a ciò che succede quando il
portlet è richiamato per rendere la sua modalità
VIEW. Prima di tutto il tempo rimanente è calcolato
a partire dall'ora corrente. Viene poi creato un TimeBean
per mantenere le ore ed i minuti che dovranno poi essere
visualizzati. Il TimeBean viene poi passato alla request
corrente usando il metodo setAttribute dell'oggeto portlet
request. Questo permetterà alla componente JSP
VIEW di ottenere il bean dalla request usando il tag
JSP useBean, come mostrato nel codice precedente. Infine,
la componente JSP che produrrà il markup HTML
per il portlet è chiamata per visualizzare i
risultati, come mostrato qui di seguito:
Figura 4 - Portlet RemainingTimePortlet
Esempio
di programmazione Web Service
Ci sono molte ragioni per le quali usare un Web service
può rappresentare un obiettivo valido ed efficiente.
Se per esempio occorre sviluppare un servizio che deve
poi essere reso disponibile a tanti client in un sistema
generico e ciascuno con i propri vincoli ambientali,
allora l'approccio ai Web services può essere
di aiuto, essendo questi in grado di fornire una piattaforma
indipendente, necessaria per integrare uniformemente
tutte le componenti del sistema.
Ritornando all'esempio descritto fin quì, verrà
ora descritta una modalità per integrare l'applicazione
portlet con un servizio Web. Verrà quindi creato
un Web service in grado di fornire i minuti e le ore
rimanenti nel giorno. Sebbene questo esempio risulterà
essere abbastanza semplice, esso permetterà comunque
di limitare la complessità del codice per porre
invece l'attenzione sugli importanti fattori nel creare,
distribuire ed integrare un servizio Web.
Questo servizio sarà poi semplicemente richiamato
dalla applicazione portlet precedentemente sviluppata.
Il primo passo per la creazione del Web service è
quello di determinare le operazioni pubbliche che dovranno
poi essere rese disponibili.
Viene quindi creata un'interfaccia RemainingTimeService:
package
esempio;
import java.util.*;
public
interface RemainingTimeService {
public
TimeBean getRemainingTime(Date date);
public Integer getRemainingHours(Date date);
public
Integer getRemainingMinutes(Date date);
}
Ora
c'è bisogno di creare un oggetto che fornisca
il servizio vero e proprio che implementa questa interfaccia,
come mostrato nella seguente classe Java:
package
esempio;
import java.util.*;
//Implemenatazione
del servizio RemainingTimeService
public class RemainingTimeServiceServerImpl implements
RemainingTimeService {
public
TimeBean getRemainingTime(Date date) {
Calendar calendar = Calendar.getInstance();
int hours = 24 - calendar.get(Calendar.HOUR_OF_DAY),
minutes = 0;
if (calendar.get(Calendar.MINUTE)
> 0) {
hours -= 1;
minutes = 60 - calendar.get(Calendar.MINUTE);
}
TimeBean timeBean = new TimeBean();
timeBean.setHours(hours);
timeBean.setMinutes(minutes);
return timeBean;
}
public
Integer getRemainingHours(Date date) {
return new Integer(getRemainingTime(date).getHours());
}
public
Integer getRemainingMinutes(Date date) {
return new Integer(getRemainingTime(date).getMinutes());
}
}
E'
necessario a questo punto costruire un progetto Web
service a partire proprio dal Java bean appena creato.
Si dovrà creare un file Enterprice Archive (
EAR) per effettuare il deployment del servizio Web sull'Application
Server e disporre poi di tutti i file descrittori SOAP
necessari appunto a descrivere il servizio tramite standard
XML.
Ci sono molti toolkit che realizzano questo step mediante
dei wizards, uno dei quali è per esempio il Web
Services Development Toolkit (WSDK) per WebSphere.
Una volta che queste componenti sono state realizzate
ed installata l'applicazione EAR sull'Application Server,
il SOAP Server si prenderà cura di inoltrare
tutte le richieste entranti. Infatti, per interagire
con questo servizio, l'applicazione chiamante deve essere
in grado di comunicare utilizzando messaggi SOAP. Sebbene
questo può rappresentare una difficoltà
in più, risulta essere però vantaggioso
in quanto fornisce interfacce standard per una migliore
interazione tra servizi, nascondendo i dettagli della
loro implementazione.
Verrà ora descritto un oggetto client che implementa
l'interfaccia RemainingTimeService e che utilizza le
API SOAP per comunicare, sempre attraverso messaggi
SOAP, con il server del servizio Web.
Si farà riferimento alle classi org.apache.soap
ed in particolare a org.apache.soap.rpc, org.apache.soap.util.xml,
org.apache.soap.encoding, org.apache.soap.soapenc.
package
esempio;
import java.net.*;
import java.util.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
public class RemainingTimeServiceClientImpl implements
RemainingTimeService {
//
Registro per specificare gli user defined objects per
la serializzazione
private SOAPMappingRegistry smr = new SOAPMappingRegistry();
//
URN per indirizzare il servizio
private String serviceURN = "urn:RemainingTimeService";
private URL soapRouter = null;
public
RemainingTimeServiceClientImpl(String host)
throws
MalformedURLException {
super();
soapRouter = new
URL("http://" + host +
"/RemainingTimeService/servlet/rpcrouter");
mapSOAPClassTypes();
}
public
TimeBean getRemainingTime(Date date) {
Vector params = new Vector();
params.addElement(new Parameter("date",
Date.class, date, null));
return (TimeBean)doCall("getRemainingTime",
params);
}
public
Integer getRemainingHours(Date date) {
Vector params = new Vector();
params.addElement(new Parameter("date",
Date.class, date, null));
return (Integer)doCall("getRemainingHours",
params);
}
public
Integer getRemainingMinutes(Date date) {
Vector params = new Vector();
params.addElement(new Parameter("date",
Date.class, date, null));
return (Integer)doCall("getRemainingMinutes",
params);
}
//
Crea la chiamata SOAP
private Object doCall(String method, Vector
params) {
try {
Call call = new
Call();
call.setSOAPMappingRegistry(smr);
call.setTargetObjectURI(serviceURN);
call.setMethodName(method);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
call.setParams(params);
//
Recupera la risposta
Response resp =
call.invoke(soapRouter, "");
if (resp.generatedFault())
{
return
null;
}
//
Recupera il risultato
Parameter result
= resp.getReturnValue();
return result ==
null ? null : result.getValue();
}
catch (SOAPException e) {
return null;
}
}
// Serializzazione
private void mapSOAPClassTypes() {
BeanSerializer beanSer = new
BeanSerializer();
smr.mapTypes(Constants.NS_URI_SOAP_ENC,new
QName(serviceURN,TimeBean"),TimeBean.class,beanSer,beanSer);
}
}
In
questo esempio non si evince la natura dinamica dei
Web services, infatti si presuppone che la locazione
host del servizio deve essere nota a priori, tanto da
essere passata come parametro per specificare il SOAP
URL.
Dopo che l'oggetto lato-client è stato costruito,
tutti i metodi di interfaccia sono pronti per essere
invocati; questi richiamano quindi il metodo doCall
per l'attuale comunicazione con il SOAP server.
Per esempio, nel metodo getRemainingTime, viene creato
un vettore per mantenere traccia dei parametri ( in
questo caso solo l'oggetto Date ).
Il vettore ed il nome del metodo vengono quindi passati
al metodo doCall, all'interno del quale viene costruito
un oggetto SOAP Call e settato con tutte le informazioni
rilevanti necessarie per comunicare con il SOAP server,
come per esempio il registro di serializzazione da usare,
l'URN, il metodo con i parametri da invocare ed il SOAP
encoding style. La chiamata è poi inizializzata
con il SOAP router URL che era stato precedentemente
costruito con l'host name fornito. Infine, viene fatto
un controllo per eventuali eccezioni generate e restituito
quindi il valore di risposta proveniente dal SOAP server.
Può essere buona pratica aggiungere a tutto ciò
un object-oriented Factory Design Pattern per fornire
un'astrazione del servizio. Per esempio, seguendo questa
strada, si potrebbe pensare di sviluppare una semplice
classe così fatta:
package
esempio;
import java.net.*;
public
class RemainingTimeServiceFactory {
public
static RemainingTimeService getInstance(String hostname)
throws MalformedURLException {
return new RemainingTimeServiceClientImpl(hostname);
}
}
Portlet
e Web Service
Modifichiamo ora il portlet richiamando il servizio
appena descritto.
La modifica del codice del portlet per poter richiamare
il Web service è molto semplice; è sufficiente
infatti modificare il solo metodo doView della classe
RemainingTimeController facendo uso delle opportune
API, come mostrato nel seguente frammento di codice:
public
void doView(PortletRequest request, PortletResponse
response)
throws
PortletException, IOException {
RemainingTimeService
service = null;
try
{
service = RemainingTimeServiceFactory.getInstance("localhost");
}
catch (Exception e) {
throw new PortletException(e.getMessage());
}
//
Inserisco il bean nella request per la JSP da usare
request.setAttribute("timeBean",
service.getRemainingTime(new Date()));
//
Richiama la View JSP per visualizzarla
getPortletConfig().getContext().include(jspHTML,
request, response);
}
Conclusioni
In questo documento si è cercato di dare una
breve descrizione della nuova tecnologia dei portlets
all'interno dello sviluppo di portali Web e di come
essi possano facilmente interagire con i Web services,
descrivendo alla fine anche un esempio completamente
funzionale, seppur limitato.
E' stato possibile notare come l'architettura delle
portlet applications sia in fondo una estensione dell'architettura
Java Servlet. Ne deriva, quindi, che molti degli aspetti
dello sviluppo dei portlets sono comuni a quelli delle
tipiche applicazioni Web. Tuttavia, occorre dire che
le funzioni uniche di un portale aggiungono complessità
al modello di applicazione, quali la presenza di più
portlets all'interno della stessa pagina Web, il controllo
di flusso del portlet nella pagina Web, le restrizioni
di visualizzazione nella interfaccia utente, la comunicazione
inter-portlet.
Una considerazione particolare deve essere però
data al disegno di una portlet application in generale,
sia per poter usufruire delle caratteristiche tipiche
di un portale, sia per evitare di diventare preda della
sua complessità.
Bibliografia
e risorse
[1] S.Hesmer, P.Fischer, T.Buckner, I.Schuster, "Portlet
Development Guide: Second Edition", IBM, 2003
[2] Doug Philips, "Developing and Debugging Portlets
Using the IBM Portal Toolkit Plug-in for WebSphere Studio
Application Developer", IBM Developer Technical
Support Center, 2002
[3] Daniel Kikuchi, "Portlet Development for WebSphere
Portal Server 1.2 Tutorial, Part1", IBM WebSphere
WebSpeed Team, 2001
[4] David B. Lection, "WebSphere Portal Server
programming: Portlet application programming, part1",
IBM, 2001
[5] David B. Lection, "WebSphere Portal Server
programming: Portlet application programming, part2",
IBM, 2001
Valerio Summo, laureato
in Ingegneria Informatica, attualmente impegnato in
un progetto di ricerca industriale e sviluppo precompetitivo
riguardo alla realizzazione di sistemi innovativi basati
sulle tecnologie della conoscenza, con utilizzo di tecniche
di Data e Web Mining. Sviluppatore in Java, orientato
ad applicazioni web J2EE, portali e Web services.
|