Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1.1 Introduzione
Nell’ambito della programmazione Java è particolarmente utile avere una certa familiarità con i WebService
e la tecnologia che li supporta. In particolare negli ultimi anni questa tecnologia si è diffusa notevolmente in
virtù della facilità di sviluppo e di condivisione di piattaforme.
Tuttavia è necessario chiarire cosa è un servizio Web: un web service è un’applicazione disponibile sul web
che si rende disponibile agli utenti attraverso una comoda interfaccia denominata WSDL. Questa interfaccia
è utile in quanto numerosi ambienti di programmazione permettono di leggerne il contenuto e di creare le
apposite classi per gestire le chiamate al servizio stesso.
2) Definire gli oggetti che dovranno essere scambiati attraverso il servizio e realizzare lo schema
xsd corrispondente.
3) Importare il progetto in Eclipse/NetBeans quindi a partire dallo schema xsd creare le classi di
binding attraverso JAXB (in alternativa sul web è disponibile un tool da linea di comando)
4) Sviluppare le classi di Endpoint e Service
5) Definire il web.xml
6) Definire il file di configurazione di SpringWS
Tuttavia questo non basta!!! Per far funzionare il servizio è necessario incapsulare la stringa all’interno di
un oggetto che per consuetudine dovrà avere (per i due casi) la seguente nomenclatura:
- ServiceRequest
- ServiceResponse
Notiamo in particolare la presenza del tag ComplexType che definisce un oggetto che contiene all’interno
un secondo oggetto di tipo stringa. Il targetNamespace ed il tns presenti nell’intestazione dello schema
devono inoltre essere modificati perché determineranno la posizione delle classi di binding nel progetto
(definiscono il package) mentre i nomi utilizzati per gli elementi saranno invece i nomi della classi di
binding.
Dopo aver completato l’editing dello schema xsd, possiamo passare all’operazione di binding delle classi
sfruttando l’opzione “Generate” presente in Eclipse e scegliendo come metodologia per il binding JAXB . Il
risultato è il seguente:
Come possiamo vedere è presente una classe di tipo ObjectFactory che contiene una serie di metodi per la
creazione di oggetti di tipo ServiceRequest e ServiceResponse. La letteratura informatica raccomanda in
generale di creare gli oggetti associati agli elementi del xsd attraverso l’utilizzo della classe ObjectFactory.
Prima di effettuare la trattazione specifica delle classi, è doveroso fare una puntualizzazione: il servizio che
andremo a sviluppare permetterà lo scambio di banali messaggi di testo ma, per effettuare tali tipi di
operazioni, dovrà ricevere un oggetto di tipo JAXBElement<ServiceRequest> e rispondere con un oggetto di
tipo JAXElement<ServiceResponse>. È chiaro che questa è una complicazione soprattutto, lo vedremo in
seguito, in merito alla ricezione dell’oggetto che ci è stato inviato ma è necessaria al fine di fornire uno
strumento che si possa utilizzare in qualsiasi circostanza. Infatti inviando un oggetto piuttosto che un
insieme di stringhe, valori numerici, ecc…. è particolarmente + semplice da gestire e utilizzare lato back
end.
La classe Endpoint viene creata come estensione di una classe astratta presente nel package di SpringWS e
denominata AbstractMarshallingPayloadEndpoint che prevede la funzionalità di deserializzazione
(unmarshalling) del payload della richiesta e la serializzazione (marshalling) della risposta. In particolare si
definisce un costruttore a due argomenti (il servizio ed il marshaller) che sarà utile al momento della
creazione del file di configurazione di SpringWS, e si sovrascrive un metodo contenuto appunto nella classe
astratta la cui firma è public Object invokeInternal(Object obj) throws Exception. Questo metodo verrà
utilizzato dalla classe di Endpoint per effettuare la chiamata effettiva al servizio effettuando appunto il
marshalling e l’unmarshalling. Il risultato è il seguente:
public Object invokeInternal(Object object) throws Exception
{
JAXBElement<ServiceRequest> request = null;
System.out.println(request);
try
{
}
catch (Exception ex)
{
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
Come possiamo vedere, abbiamo un ciclo if in cui verifichiamo che, la richiesta inviata sia tipo JAXBElement
o tipo ServiceRequest: nel primo caso l’oggetto cosi com’è viene utilizzato dal metodo mentre nel secondo
caso si crea l’oggetto JAXBElement sfruttando il costruttore in cui passiamo il QName (classe che definisce il
QualifiedName come specificato nel xsd, rappresentato dall’URI dell’oggetto – il package se vogliamo - e dal
localPart - nome dell’oggetti - ), la classe dell’oggetto e l’oggetto ricevuto dalla richiesta.
Si crea quindi la risposta sfruttando il metodo dell’oggetto service a cui passiamo la richiesta di tipo
JAXBElement che abbiamo appositamente creato.
La classe Service è molto + semplice rispetto alla classe di Endpont in quanto prevede un unico metodo a
cui possiamo dare un nome a nostra scelta ma ricordando che tale metodo deve ricevere un oggetto di tipo
JAXBElement<ServiceRequest> e deve restituire un oggetto di tipo JAXBElement<ServiceResponse>. Questo
è il listato del codice:
public JAXBElement<ServiceResponse> invioSaluto(JAXBElement<ServiceRequest> request)
{
ServiceRequest req = request.getValue();
ServiceResponse res = new
org.altervista.marcoamato.types.ObjectFactory().createServiceResponse();
System.out.println(req.getSalutoRichiesta());
res.setSalutoRisposta(req.getSalutoRichiesta());
return response;
}
In questo caso sostanzialmente abbiamo fatto l’operazione inversa all’Endpoint in quanto costruiamo un
oggetto JAXBElement<ServiceResponse> attraverso l’oggetto ServiceResponse di cui abbiamo settato la
risposta con il metodo “setSalutoRisposta” creato al momento del binding con JAXB.
1.5 Web.xml e SpringWS – servlet
Dopo aver dunque generato le classi necessarie per implementare il servizio, definiamo gli ultimi due
componenti ovvero il web.xml ed il file di configurazione di SpringWS. Infatti nell’ambito di un progetto
SpringWS sfruttiamo sostanzialmente le caratteristiche di un progetto Web Java in cui è presente il
web.xml: si configurerà questo file in modo che risponda ad un servlet di Spring mappata attraverso
ulteriore file di configurazione. Il descrittore è dunque il seguente:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-
app_2_4.xsd">
<display-name>MyService</display-name>
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>
org.springframework.ws.transport.http.MessageDispatcherServlet
</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Il file è del tutto simile a quelli comunemente utilizzati in altre applicazioni web sebbene osserviamo la
presenza della servlet di Spring ovvero la classe MessageDispatcherServlet che permette l’invio e la
ricezione dei messaggi attraverso servlet. D’altra importante è il server-name che definirà non solo il nome
della servlet ma anche il nome del file di configurazione come: spring-ws-servlet.xml. Si aggiunge dunque al
nome della servlet il suffisso –servlet.
Leggiamo il listato in modo che sia chiaro come sia stato editato:
Per provare il progetto basterà utilizzare SoapUi e creare un nuovo progetto allegando il wsdl.