Mokabyte

Dal 1996, architetture, metodologie, sviluppo software

  • Argomenti
    • Programmazione & Linguaggi
      • Java
      • DataBase & elaborazione dei dati
      • Frameworks & Tools
      • Processi di sviluppo
    • Architetture dei sistemi
      • Sicurezza informatica
      • DevOps
    • Project Management
      • Organizzazione aziendale
      • HR
      • Soft skills
    • Lean/Agile
      • Scrum
      • Teoria della complessità
      • Apprendimento & Serious Gaming
    • Internet & Digital
      • Cultura & Società
      • Conferenze & Reportage
      • Marketing & eCommerce
    • Hardware & Tecnologia
      • Intelligenza artificiale
      • UX design & Grafica
  • Ultimo numero
  • Archivio
    • Archivio dal 2006 ad oggi
    • Il primo sito web – 1996-2005
  • Chi siamo
  • Ventennale
  • Libri
  • Contatti
  • Argomenti
    • Programmazione & Linguaggi
      • Java
      • DataBase & elaborazione dei dati
      • Frameworks & Tools
      • Processi di sviluppo
    • Architetture dei sistemi
      • Sicurezza informatica
      • DevOps
    • Project Management
      • Organizzazione aziendale
      • HR
      • Soft skills
    • Lean/Agile
      • Scrum
      • Teoria della complessità
      • Apprendimento & Serious Gaming
    • Internet & Digital
      • Cultura & Società
      • Conferenze & Reportage
      • Marketing & eCommerce
    • Hardware & Tecnologia
      • Intelligenza artificiale
      • UX design & Grafica
  • Ultimo numero
  • Archivio
    • Archivio dal 2006 ad oggi
    • Il primo sito web – 1996-2005
  • Chi siamo
  • Ventennale
  • Libri
  • Contatti

Nel numero:

152 giugno
, anno 2010

Realizziamo un Web Service con Spring-WS

V parte: Gestire versioni multiple dello stesso Web Service

Luigi Bennardis
Luigi Bennardis

Luigi Bennardis si è laureato in Scienze Statistiche ed Economiche all’Università di Roma. Si occupa di informatica da un po’ di tempo ed è attualmente impegnato su tematiche DevOps. Nel tempo libero ancora gioca a basket, nuota ed è appassionato di elettronica vintage.

MokaByte

Realizziamo un Web Service con Spring-WS

V parte: Gestire versioni multiple dello stesso Web Service

Picture of Luigi Bennardis

Luigi Bennardis

  • Questo articolo parla di: Architetture dei sistemi, Frameworks & Tools

Terminiamo questa serie su Spring-WS illustrando alcune caratteristiche di questo framework che ci permettono di rendere più agevole e flessibile la pubblicazione di un Web Service. In questo articolo analizzeremo come sia possibile gestire versioni multiple dello stesso servizio definendo un interceptor che applica, al payload XML, una trasformazione XSLT.

Il mese scorso ci eravamo lasciati, tenendoci per “ultima cartuccia” la gestione di versioni multiple dello stesso Web Service. In questa quinta e ultima parte, concludiamo con tale argomento la nostra serie su Spring-WS.

Implementazione dell’interceptor di trasformazione XSLT

Sempre a livello di definizione del mapping di un endpoint, Spring-WS definisce la classe PayloadTransformingInterceptor quale interceptor basato su stylesheet XSLT. Attraverso questo interceptor è possibile trasformare il payload del messaggio SOAP mediante una specifica trasformazione XSLT. Vedremo come l’adeguamento dell’XML scambiato tra client ed endpoint ci consente di gestire, senza duplicazioni di codice, versioni multiple dello stesso servizio.

Lo scenario di applicazione è quello in cui l’interfaccia di un servizio subisce un adeguamento. Terminata la definizione del nuovo contratto e l’implementazione della logica applicativa del servizio, ci troviamo a dover gestire la migrazione dei client che consumavano il vecchio contratto. I client potrebbero semplicemente ricreare i loro proxy a partire dalla pubblicazione del nuovo WSDL per poi adeguare il software alle nuove informazioni definite nella nuova interfaccia. Potremmo rendere più efficiente questa migrazione se riuscissimo a mantenere in linea i due servizi senza ridondanze di implementazione. In questo modo i client potrebbero adeguarsi gradualmente alla nuova interfaccia senza brusche interruzioni del business, fino alla completa dismissione del vecchio servizio.

Nell’esempio riportato, la modifica del contratto del servizio consiste nell’aggiunta nella request di due campi, la nazione e il codice della tessera che fidelizza il cliente; conseguentemente ne è stata adeguata la logica applicativa ed è stato pubblicato il nuovo servizio. Viene quindi definito un opportuno mapping per le richieste SOAP dei client che implementavano la vecchia interfaccia. Questo fa sì che le richieste di questi client vengano indirizzate verso l’endpoint implementato dalla nuova interfaccia ma per il cui mapping è definita la trasformazione XSLT transformRequest.xslt, che adegua il messaggio SOAP alla nuova interfaccia.

Nell’esempio, la trasformazione XSLT completa il messaggio XML con dei valori di default gestiti (“ITALIA”, “999999”).

Di seguito, nelle figure, la definizione del mapping e dell’interceptor di trasformazione XSLT associato, da applicare ai messaggi che dichiarano nella busta SOAP il namespace del vecchio contratto di servizio.

Figura 1 – Definizione dell’interceptor di trasformazione XSLT.

 

 

 

Figura 2 – Esempio di payload di request secondo la vecchia interfaccia del servizio.

 

Figura 3 – Payload di request trasformato dallo stylesheet XSLT.

 

 

Riportiamo di seguito lo stylesheet XSLT di trasformazione. Per ragioni di leggibilità, nei tipi complessi sono state omesse alcune direttive “xsl:value-of select”, mentre abbiamo evidenziato le direttive che adeguano la request. Nell’esempio allegato (scaricabile dal menu in alto a sinistra) il lettore troverà il file nella sua integrità.

 

 


Figura 4 – Stylesheet XSLT di trasformazione.

 

Implementazione dell’interceptor di trasformazione custom

 

In tema di implementazione di un endpoint, Spring-WS fornisce la possibilità di creare una classe che estende PayloadTransformingInterceptor dove eventualmente codificare la  trasformazione del messaggio SOAP scambiato o gestire operazioni prima che la request venga inviata alla classe di endpoint.

Analogamente a quanto fatto per la PayloadTransformingInterceptor, indichiamo questa classe custom nel bean che definisce l’endpoint mapping nel file di configurazione di Spring-WS.

Figura 5 – Definizione di un endpoint custom.

 

Nel fragment di codice riportato di seguito, troviamo l’esempio più semplice di implementazione di questa classe, dove, nei metodi che eseguono l’overload dei metodi handleRequest e handleResponse, vengono richiamati i metodi che effettuano la trasformazione XSLT nella classe estesa.

publicclass TransformazioneEsplicitaVecchiMessaggiDOM
                    extends PayloadTransformingInterceptor {
       publicboolean handleRequest(MessageContext messageContext, Object endpoint)
                    throws Exception { 
             returnsuper.handleRequest(messageContext, endpoint);
       }     
       publicboolean handleResponse(MessageContext messageContext, Object endpoint)
                    throws Exception {
              returnsuper.handleResponse(messageContext, endpoint);
       }

I metodi handleRequest e handleResponse, ottenendo in input le variabili messageContext ed endpoint, quando ritornano true informano il framework circa la prosecuzione dell’elaborazione, mentre con false interrompono la catena di chiamate verso l’endpoint.

messageContext

L’interfaccia MessageContext, implementata dalla classe org.springframework.ws.context.DefaultMessageContext, rappresenta il contenitore del messaggio web contenente sia la request che la response sotto forma di SaajSoapMessage.

Figura 6 – Variabile messageContext.

 

SaajSoapMessage è l’implementazione specifica di SAAJ dell’interfaccia SoapMessage. Creata attraverso una SaajSoapMessageFactory rappresenta una classe wrapper di SOAPMessage che rappresenta a sua volta una astrazione per i messaggi SOAP.

Un oggetto SOAPMessage consiste di un fragment SOAP e uno o più attachment opzionali. Ogni SOAPMessage contiene di default gli oggetti:

  • SOAPPart
  • SOAPEnvelope
  • SOAPBody
  • SOAPHeader

in corrispondenza dei quali si ottengono gli oggetti Part, Envelope, Body e Header

SOAPPart sp = message.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
SOAPBody sb = se.getBody();
SOAPHeader sh = se.getHeader();

Sarà quindi possibile accedere alla request attraverso l’interfaccia WebServiceMessage che rappresenta un messaggio XML protocol-agnostic.

WebServiceMessage messageRequest = messageContext.getRequest();

endpoint

Questa variabile definisce la classe che implementa l’endpoint del servizio e il tipo di marshalling dichiarato nel file di configurazione di Spring-WS.

Figura 7 – Variabile endpoint.

 

Una interessante implementazione di questo tipo è quella descritta nell’articolo [1], dove a fronte dello stesso endpoint viene presentata una trasformazione da RCP-encoded a document-literal analizzando l’encoding style del payload.

Senza annoiare il lettore, che rimandiamo al sorgente allegato dove troverà la definizione di un interceptor custom in cui viene codificato attraverso DOM l’adeguamento della request alla nuova interfaccia, riportiamo di seguito il fragment di implementazione che ottiene un oggetto Document delle api DOM a partire dalla variabile messageContext di input.

//***MESSAGGIO WEB CHE CONTIENE REQUEST E RESPONSE
WebServiceMessage message = messageContext.getRequest();
Transformer transformerSource = createTransformer();
//***OTTENIAMO UN DOMResult
DOMResult domResult = new DOMResult(); 
transformerSource.transform(message.getPayloadSource(), domResult);
Document doc = null;
doc = (Document)domResult.getNode();

Conclusioni

Spesso il rischio di potersi trovare di fronte a scenari evolutivi non prevedibili rappresenta l’ostacolo all’introduzione nello sviluppo di un framework che, con il mutare delle esigenze, potrebbe rivelarsi restrittivo. In questa serie di articoli abbiamo introdotto Spring-WS con l’obiettivo di agevolare lo sviluppo contract-first di un Web Service, scoprendone poi alcune caratteristiche di flessibilità ed estendibilità. Abbiamo visto come sia possibile implementare il parser dell’XML attraverso le diverse librerie della famiglia DOM (W3C DOM, JDOM, dom4j) o con le meglio performanti SAX o StAX, concludendo con le tecniche di marshalling dell’XML, attraverso l’integrazione di JAXB, Castor, XMLBeans, JiBX o XStream, che eliminano l’effort della codifica. Aspetto che assume ancor più significato in congiunzione alla definizione degli interceptor che eseguono la validazione dell’XML scambiato e lo tracciano su file di log.

Abbiamo anche avuto modo di evidenziare come sia possibile gestire versioni diverse dell’interfaccia dello stesso servizio attraverso gli interceptor di trasformazione XSLT. Naturalmente l’overhead computazionale introdotto, direttamente proporzionale alla complessità dell’XML, potrebbe non essere trascurabile e rivelarsi critico. In questo senso potremmo mitigare questo effetto attraverso l’implementazione di un interceptor di trasformazione custom, adeguando l’XML in modo più performante, per esempio attraverso le API STAX, perdendo però di generalizzazione rispetto a una trasformazione XSLT.

Riferimenti

[1] Tareq Abedrabbo, “Migrating Smoothly from rpc/encoded to document/literal Web Services with Spring-WS”

http://www.cafebabe.me/2007/03/migrating-smoothly-from-rpcencoded-to.html

[2] Log4J

http://logging.apache.org/

[3] SAAJ

https://saaj.dev.java.net/

[4] W3C DOM

http://www.w3.org/DOM/

[5] JDOM

http://www.jdom.org/

[6] Dom4j

http://www.dom4j.org/

[7] SAX

http://www.saxproject.org/

[8] StAX

http://stax.codehaus.org/Home

[9] JAXB

https://jaxb.dev.java.net/

[10] Castor

http://www.castor.org/

[11] XMLBeans

http://xmlbeans.apache.org/

[12] JiBX

http://jibx.sourceforge.net/

[13] XStream

http://xstream.codehaus.org/

 

Luigi Bennardis
Luigi Bennardis

Luigi Bennardis si è laureato in Scienze Statistiche ed Economiche all’Università di Roma. Si occupa di informatica da un po’ di tempo ed è attualmente impegnato su tematiche DevOps. Nel tempo libero ancora gioca a basket, nuota ed è appassionato di elettronica vintage.

Facebook
Twitter
LinkedIn
Picture of Luigi Bennardis

Luigi Bennardis

Luigi Bennardis si è laureato in Scienze Statistiche ed Economiche all’Università di Roma. Si occupa di informatica da un po’ di tempo ed è attualmente impegnato su tematiche DevOps. Nel tempo libero ancora gioca a basket, nuota ed è appassionato di elettronica vintage.
Tutti gli articoli
Nello stesso numero
Loading...

Aspetti sociali del web

III parte: La geografia di Internet

La programmazione RIA con GWT/GXT

IV parte: Lavorare con i dati

GraniteDS: Flex incontra Java

Esempi pratici con Tide

Nella stessa serie
Loading...

Realizziamo un Web Service con Spring-WS

IV parte: Endpoint del servizio e routing del payload

Realizziamo un Web Service con Spring-WS

III parte: Modifica di un Web Service creato con Spring-WS

Realizziamo un Web Service con Spring-WS

II parte: Sviluppo e pubblicazione del Web Service

Realizziamo un Web Service con Spring-WS

I parte: Approccio allo sviluppo e primi passi

Mokabyte

MokaByte è una rivista online nata nel 1996, dedicata alla comunità degli sviluppatori java.
La rivista tratta di vari argomenti, tra cui architetture enterprise e integrazione, metodologie di sviluppo lean/agile e aspetti sociali e culturali del web.

Imola Informatica

MokaByte è un marchio registrato da:
Imola Informatica S.P.A.
Via Selice 66/a 40026 Imola (BO)
C.F. e Iscriz. Registro imprese BO 03351570373
P.I. 00614381200
Cap. Soc. euro 100.000,00 i.v.

Privacy | Cookie Policy

Contatti

Contattaci tramite la nostra pagina contatti, oppure scrivendo a redazione@mokabyte.it

Seguici sui social

Facebook Linkedin Rss
Imola Informatica
Mokabyte