Esercitazione WSDL Top-Down


1. Prerequisiti

Runtime Environment. In Eclipse, configurare il proprio ambiente di runtime Tomcat. Selezionare Window > Preferences > Server > Runtime Environment > New... Nella finestra che si apre, selezionare Apache Tomcat 7 e indicare il folder di installazione (La directory padre della webapps dove eseguite i deploy).

CXF. Scaricare e decomprimere la versione 3.x di Apache CXF. Selezionare Window > Preferences > Web Services > CXF 2.x Preferences > Add... , indicare il folder dove avete appena decompresso l'applicazione, selezionare il checkbutton e cliccare Finish.

2. Esercizio: WSDL

Obiettivo di questo esercizio è descrivere un servizio web tramite WSDL che emula lo Shopping Service di eBay implementando l'operazione GetCategoryInfo .

Step 1. Creare un nuovo WSDL. Creiamo un nuovo Dynamic Web Project di nome shopping e selezioniamo File > New.. > WSDL File . Nel wizard di creazione indichiamo come nome del file Shopping.wsdl e come namespace http://di.unipi.it/lai/shopping/ . Selezionare Finish e verificare che venga creato lo scheletro di un WSDL.

Step 2. Types. L'elemento types che contiene gli schemi xml dei messaggi utilizzati. Il nostro servizio utilizza i messaggi definiti dallo schema di eBay, quindi possiamo riusarlo. Copiamo quindi lo ShoppingService.xsd in nella stessa cartella del WSDL. Rimuoviamo la definizione dello schema generata da Eclipse e inseriamone una nuova indicando il targetNamespace di ebay ( urn:ebay:apis:eBLBaseComponents ) ed aggiungiamo include dello schema.

Step 3. Messages. Completata la definizione degli elementi che utilizzeremo nel servizio, procediamo con la definizione dei messaggi. L'operazione di GetCategoryInfo è una operazione sincrona, quindi con richiesta e risposta. Dobbiamo quindi definire due messaggi corrispondenti alla richiesta e alla risposta. Lo scheletro generato da Eclipse contiene già la definizione di due messaggi, quindi è sufficiente modificarli indicando i corretti root element ebay:GetCategoryInfoRequest e ebay:GetCategoryInfoResponse, ricordandoci di aggiungere il riferimento al prefisso ebay nell'intestazione del file WSDL (xmlns:ebay="urn:ebay:apis:eBLBaseComponents").

Step 4. Port-Types. Definiti i messaggi, procediamo con il portType, ovvero l'interfaccia astratta del servizio contenente le operazioni da offrire. Lo scheletro generato da Eclipse contiene già un portType con una operazione sincrona che utilizza i messaggi definiti in precedenza come richiesta e risposta. Per adattarlo alle nostre esigenze, basta cambiare il nome all'operazione con GetCategoryInfo .

Step 5. Binding. Completato il portType, ovvero l'interfaccia astratta del servizio, definiamone il binding, ovvero l'implementazione. Con il binding indichiamo il formato dei messaggi, il protocollo di trasporto e la codifica. Nel nostro caso, vogliamo indicare l'uso del SOAP su HTTP con codifica Document/Literal. Lo scheletro di binding generato da Eclipse è già configurato in questo modo, quindi è sufficiente correggere il nome dell'operazione e personalizzare il valore dell'header SOAPAction.

Step 6. Service. L'elemento service specifica il punto di accesso al servizio. Trattandosi di un binding HTTP, verrà indicata la URL di invocazione, ma in questa fase non sappiamo quale sarà la URL del servizio, quindi possiamo lasciare quella generata da Eclipse. Validiamo il WSDL e verifichiamo che non siano segnalati errori.

3. Esercizio: Web Service Top Down

Obiettivo di questo esercizio è generare, implementare e deployare un Web Service a partire dal WSDL utilizzando Eclipse e CXF

Step 1. Configurare il Build Path. Aggiungiamo le librerie di CXF al build path del progetto. Selezioniamo il progetto e Project > Properties > Java Build Path > Libraries > Add library... aggiungere la libreria CXF configurata nei prerequisiti.

Step 2. Generazione dello skeleton. Cliccare con il tasto destro il WSDL creato nell'esercizio precedente e selezionare Web Services > Generate Java Bean Skeleton . Verificare che la finestra di dialogo successiva presenti questi valori:

  • Web Service Type: Top Down

  • Service definition: path al WSDL

  • Slider di generazione: Assemble Service

  • Server runtime: Apache Tomcat

  • Web Service runtime: Apache CXF 2.x

  • Service Project: il progetto di destinazione

Selezionare Finish e verificare che siano generati i seguenti componenti:

  • WebContent/WEB-INF/web.xml : è il deployment descriptor. Nelle precedenti esercitazioni era sostituito dalle annotazioni, ma adesso è necessario. Definisce che tutte le chiamate alla URL /services/* siano gestite dalla servlet di CXF configurata dal file cxf-beans.xml

  • WebContent/WEB-INF/cxf-beans.xml : script di configurazione per la servlet di CXF. Definisce l'endpoint del Web Service, la URL a cui risponde, la classe che lo implementa, il WSDL che lo descrive etc.. Inoltre è preconfigurato per utilizzare la funzionalità di Logging di CXF che esegue il log di tutti i messaggi transitati.

  • Java Resources/src/ebay.apis.eblbasecomponents : package con le classi annotate JAXB corrispondenti agli elementi definiti dall'XML Schema di eBay generate con XJC.

  • Java Resources/src/it.unipi.di.lai.shopping : package con le classi annotate JAXWS corrispondenti agli elementi definiti dal WSDL del servizio generate con WSDL2JAVA di CXF. Comprendono:

    • Interfaccia del servizio, generata con il nome del portType

    • Implementazione del servizio, generata con il suffisso Impl

Se il codice sorgente non fosse generato a causa di errori in console, eseguire lo stesso comando visualizzato in console eclipse da un terminale, eliminando dal path riferito nel comando la directory .cxftmp. In questo caso il comando wsdl2java è disponibile all'interno dell'archivio di CXF, scaricato all'inizio dell'esercitazione.

Step 3. Implementazione. Apriamo e modifichiamo la classe che implementa l'interfaccia del servizio. Il generatore ha prodotto un'implementazione che valorizza tutti i possibili campi della risposta per aiutarci nello sviluppo. Per il momento possiamo mantenere questa implementazione, su cui agiremo successivamente.

Step 4. Deploy e verifica. Esportare il progetto come WAR chiamato shopping.war e deployarlo in Tomcat verificando che non ci siano errori. Verificare che sia accedibile la servlet di CXF all'indirizzo http://localhost:8080/shopping/services/ e che venga visualizzata la lista dei servizi con il link al WSDL del servizio.

4. Esercizio: Web Service Client Top Down

Obiettivo di questo esercizio è generare, implementare ed eseguire Client per il Web Service sviluppato nell'esercizio precedente.

Step 1. Predisporre il progetto. Creare un nuovo Dynamic Web Progect ed aggiungere le librerie di CXF al build path del progetto.

Step 2. Generazione dello stub. Selezionare File > New... > Web Services Client . Verificare che la finestra di dialogo successiva presenti questi valori:

  • Service definition: la URL del WSDL del servizio deployato in precedenza

  • Slider di generazione: Assemble

  • Server runtime: Apache Tomcat

  • Web Service runtime: Apache CXF 3.x

  • Client Project: il progetto di destinazione

Selezionare Finish e verificare che siano generati i seguenti componenti:

  • ebay.apis.eblbasecomponents : package con le classi annotate JAXB corrispondenti agli elementi definiti dall'XML Schema di eBay generate con XJC.

  • it.unipi.di.lai.shopping : package con le classi annotate JAXWS corrispondenti agli elementi definiti dal WSDL del servizio generate con WSDL2JAVA di CXF. Comprendono:

    • Una factory per l'implementazione di client per il servizio.

    • Una implementazione di un client.

Step 3. Implementazione. Apriamo e modifichiamo la classe che implementa il client del servizio. Il generatore ha incluso un'implementazione che valorizza tutti i possibili campi della richiesta per aiutarci nello sviluppo.

Step 4. Invocazione. Eseguire il client e verificare il corretto funzionamento. Inoltre verificare che nei log di Tomcat vengano loggati i messaggi SOAP in transito, compresivi degli header http.

Step 5. Analisi. Analizzare e provare a modificare l'implementazione del server, in modo da restituire un elenco di categorie in stile EBay, e l'implementazione del client per stampare l'elenco delle categorie restituite. Nel farlo analizzare come siano mappati gli elementi xml con le corrispondenti classi Java anche facendo riferimento alla sezione Output della documentazione eBay.

5. Esercizio: Indipendenza dall'ambiente

I Web Service ed i Client prodotti fino ad adesso sono fortemente vincolati all'ambiente di sviluppo. Con molta probabilità, non saremmo in grado di deployare il Web Service od eseguire il Client in altri ambienti. Eliminiamo le dipendenze dall'ambiente di sviluppo.

Step 1. Includere il WSDL nel WAR. L'annotazione @WebService riporta il parametro wsdlLocation con il path del WSDL da pubblicare. Il valore assegnato dal generatore è quello del path assoluto, valido solo nell'ambiente di sviluppo. Spostiamo il file all'interno della cartella WebContent in modo che sia incluso nel WAR di esportazione e modifichiamo il valore di wsdlLocation con il path relativo alla root del WAR (eg: WEB-INF/wsdl/Shopping.wsdl )

Step 2. Includere il WSDL nel Client. Tutte le volte che invochiamo il client, il Web Service logga, prima dell'invocazione SOAP, una GET al WSDL. Questo perché per instanziare il client, la factory ha bisogno del WSDL del servizio che consuma e lo recupera invocando la URL fornita in fase di generazione. Questo comportamento, oltre ad essere molto inefficiente, è dipendente dalla riuscita della GET. Modifichiamo il Client in modo da instanziare lo stub fornendo un WSDL locale, non tramite URL remota.

Step 3. Specificare la URL di invocazione del Client. Gli stub utilizzano come URL di invocazione quella indicata nel WSDL. Questo potrebbe non essere corretto, ad esempio nel caso si debba invocare un Proxy applicativo che media le richieste. Modificare il codice in modo da specificare la URL di invocazione:

((BindingProvider) port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://.....");

6. Soluzione

Scaricare l'archivio della soluzione e importarlo in Eclipse con File > Import > General > Existing Project creando cosi i progetti WebService e WebService Client.

Aggiungere ad entrambi i progetti le librerie CXF e al progetto WebService le librerie Lai API v.1.0.4.

Esportare il progetto WebService come webservice.war in Tomcat e verificare il corretto deploy richiedendo il WSDL del servizio alla url http://localhost:8080/webservice/services/SOAP?wsdl

Eseguire la classe Shopping_Client del progetto WebService Client e verificarne il corretto funzionamento.

Footer BGFooter BG
Tito Flagella - © 2007-2015