Web Services con Java5: La nuova piattaforma JAXWS - WSIT

II parte: Web Services e Handler applicatividi

Gli Handler sono uno strumento molto utile soprattutto per 2 scenari: compensazione dei fault e integrazione con altri sistemi. In questo articolo vedremo come si implementano usando la piattaforma Open Source per i Web Services offerta da Sun.

Gli Handler

Un Handler per i Web Services è un componente software in grado di eseguire operazioni a ogni richiesta, risposta o fault. Anche se non esiste un vero limite alle operazioni svolte dagli Handler, essi in genere, visto il punto in cui intervengono, eseguono i seguenti tipi di attività:

  • tracciamento di richieste e risposte
  • modifica della richiesta, della risposta o del fault
  • modifica dei dati contenuti nel contesto dei Web Services
  • compensazione dei fault

Esiste inoltre un'altra categoria di Handler che viene usata per problematiche legate alla sicurezza ma non verranno trattati in questo articolo.

Contesto di applicazione

Le attività indicate per gli Handler sono riconducibili a due scenari molto importanti: l'integrazione e la compensazione di eventuali errori.
In effetti l'uso massiccio dei Web Services è strettamente legato all'evoluzione delle applicazioni verso modelli architetturali di tipo SOA.In questi modelli l'applicazione o il sistema informativo è composto da un insieme di servizi completamente separati tra loro (e a volte gestiti da organizzazioni diverse) e quindi può essere necessario implementare attività di monitoring per riuscire a seguire i flussi delle singole richieste. In questo caso l'uso di un Handler è una opzione importante poiche‘ consente di tracciare le richieste e le risposte dei singoli servizi e quindi verificare, in caso di errore, quale di questi non ha funzionato correttamente.
Anche la possibilità di modificare la richiesta, la risposta o il fault si sposa molto bene con gli scenari di integrazione. Questa funzionalità può essere usata, per esempio, per arricchire il messaggio di tutte le informazioni opzionali con dei dati di default.
Inoltre è possibile ricavare delle informazioni infrastrutturali che non si vogliono esporre direttamente nella firma del servizio, ma che possono essere dedotte in qualche modo e passate al servizio, per esempio, tramite il MessageContext.
Infine possiamo invocare altri servizi o compensare eventuali condizioni di errore.
Questa possibilità consente di creare dei sistemi basati sul paradigma ad eventi in modo tale da iniziare determinate attività solo in corrispondenza di richieste specifiche.

Questo tipo di responsabilità vengono facilmente collocate all'interno di un Handler perch� esso può lavorare in modo trasversale a tutti i servizi e lo può fare sia durante la richiesta che durante la risposta.

Come si implementa un Handler

Un Handler è una normale classe Java che può estendere una delle seguenti interfacce:

javax.xml.ws.handler.soap.SOAPHandler
javax.xml.ws.handler.LogicalHandler

Ecco un esempio di handler che estende l'interfaccia LogicalHandler:

public class MyLogicaHandler
    implements LogicalHandler {
   
   
    public boolean handleFault(LogicalMessageContext ctx) {
        // Something to do ...
        return true;
    }
   
    public boolean handleMessage(LogicalMessageContext ctx) {
        Boolean direction = (Boolean) ctx.get(
            LogicalMessageContext.MESSAGE_OUTBOUND_PROPERTY);
   
        // Something to do ...
        return true;
    }
   
    public void close(MessageContext arg0) {
        // nothing to do.
    }

}

Ed ecco un esempio di handler che estende l'interfaccia SOAPHandler:

public class MySoapHandler implements SOAPHandler {

    public void close(MessageContext arg0) {
    }
   
    public Set getHeaders() {
        return null;
    }
   
    public boolean handleFault(SOAPMessageContext ctx) {
        return true;
    }
   
    public boolean handleMessage(SOAPMessageContext ctx) {
        // Something to do ...
        return true;
    }
}

Se si utilizza SOAPHandler si avrà un accesso completo al messaggio soap, compresi gli header, mentre LogicalHandler si astrae dal protocollo utilizzato e può accedere al payload del messaggio.
Come si può vedere l'implementazione del Handler nei due casi differisce solo per il tipo di contesto utilizzato, il quale fornisce appunto le funzionalità citate in precedenza.

Da notare, inoltre, che i due metodi principali (handleMessage e handleFault) ritornano un boolean, il quale condiziona la logica del metodo stesso, infatti se il valore ritornato è true allora il processo continua, mentre se è false allora il processo viene bloccatoPer esempio, se vogliamo bloccare tutti i fault allora nel metodo handleFault ritorneremo false e di conseguenza il client (in caso di eccezione) non vedrà arrivare nessuna risposta.

Il metodo handleMessage è in grado di gestire sia le richieste che le risposte verificando tramite il MessageContext la "direzione" del messaggio (inbound o outbound).
Una volta ottenuto il messaggio è quindi possibile applicare qualsiasi tipo di trasformazione o interagire con qualsiasi altro componente per passare informazioni o iniziare attività collaterali.

Come applicare un Handler a un Web Service

Una volta definito l'Handler è necessario indicare a quali servizi applicarlo.
È possibile fare questa operazione sia dentro le classi Java tramite una normale annotazione che tramite un file di configurazione.

Uso dell'annotazione

Tra le annotazioni previste dallo standard [JSR 181] ne esiste una chiamata @HandlerChain la quale accetta 2 parametri: file e name (opzionale), dove file rappresenta il percorso in cui trovare il file di configurazione degli Handler e name rappresenta il nome dell'HandlerChain da applicare al servizio.

@WebService
@HandlerChain(file="handlers.xml")
public class MyServiceImpl {}
    // ...
}

Il file indicato deve quindi contenere la "catena" degli handler da applicare secondo un file di definizione standard simile al seguente.



   
       
            MySoapHandler
       

   

Naturalmente è possibile indicare più Handler, i quali verranno applicati nell'ordine di definizione.

Uso degli Handler in SUN Metro

Nel caso si utilizzi come Runtime Web Services Metro (si veda [JAXWS)] allora possiamo indicare gli Handler anche usando il suo specifico file di configurazione chiamato sun-jaxws.xml (vedere [Moka127]).
Questo file indica quali sono gli Endpoint (cioè i servizi) da pubblicare e quali sono gli Handler da applicare ad ognuno di essi.


            name='moka-ws'
        implementation='it.mokabyte.MyWSImpl'
        url-pattern='/'>

       
           
               
                    MySoapHandler
               

           

       

   

L'uso di questo file ci consente di non inserire delle annotazioni all'interno del codice e quindi di applicare gli Handler semplicemente tramite una configurazione centralizzata senza ricorrere a modifiche dentro al codice sorgente.

Conclusioni

In questo articolo abbiamo visto che gli Handler sono dei componenti che possono essere implementati tramite una normale classe Java che estende una interfaccia nota e un file di configurazione.
Questo è un approccio classico nel mondo Java e Java EE in particolare per cui tutti gli sviluppatori dovrebbero trovarsi a proprio agio con questa procedura.
Abbiamo poi capito a cosa servono: grazie alla loro grande flessibilità infatti sono molto utili in scenari di integrazione, monitoring e compensazione.
Attività importantissime in particolare se correlate a elementi architetturali come i Web Services che sono quasi sempre stateless e fortemente separati tra loro.
Possiamo quindi concludere dicendo che gli Handler sono molto utili e che devono far parte della pila delle conoscenze di uno sviluppatore Java moderno.
Abbiamo infine visto che l'introduzione del Runtime di sun (Metro/Wsit) non complica lo sviluppo in modo inutile, ma anzi fornisce la possibilità di centralizzare la configurazione degli Handler nel file in cui si configurano gli Endpoint stessi evitando così di disperdere l'informazione in più punti.

Note

Nel precedente articolo su MokaByte [Moka127] è stato presentato un progetto in cui si sviluppano dei Web Services usando Metro.
La presentazione degli Handler è la naturale continuazione di quel articolo e quindi per poter creare un progetto in cui inserire un componente di questo tipo è sufficiente utilizzare quello precedentemente descritto senza particolare accorgimenti.
La struttura delle directory e i target Ant rimangono invariati e le librerie incluse sono sufficienti a sviluppare dei semplici servizi con un Handler, per esempio, che traccia richiesta, risposta ed eventuali eccezioni.

Riferimenti

[Moka127] Web Services con Java5: La nuova piattaforma JAXWS - WSIT - I parte
http://www2.mokabyte.it/cms/iconservlet?articleId=8LB-HV5-AXM-UTT_7f000001_33280598_8a400966

[WSI] WSI Organisation home page
http://www.ws-i.org/

[JAXWS] JAXWS Metro Home page
https://jax-ws.dev.java.net/

[NB] Building JAX-WS 2.0 Services with NetBeans 5.0
http://www.netbeans.org/kb/50/jaxws20.html

[JSR 181]
http://jcp.org/en/jsr/detail?id=181

 

Condividi

Pubblicato nel numero
128 aprile 2008
Appassionato di informatica da prima che arrivasse internet, progetta e organizza sistemi informativi di grandi aziende. https://it.linkedin.com/in/mcasoni
Articoli nella stessa serie
Ti potrebbe interessare anche