JAX-WS Interceptor

Molte delle funzionalità JAX-WS che JBossWS fornisce in WildFly sono ottenute attraverso la corretta integrazione dello stack JBoss Web Services con la maggior parte dei moduli di progetto Apache CXF (nel seguito JBossWS-CXF). Tale integrazione è principalmente finalizzata a:

  1. Consentire l’utilizzo di API standard (incluso JAX-WS) su WildFly.
  2. Includere le funzionalità avanzate di Apache CXF (incluso WS-*).

In questo articolo vediamo come, attraverso l’integrazione JBossWS-CXF, sia possibile intercettare le chiamate web-service, in ingresso o in uscita, al fine di leggere o modificare le informazioni scambiate nella request o nella response del servizio.

Il Progetto

Riprendiamo il progetto jaxws-webapp che abbiamo utilizzato nell’articolo Primi Passi con JAX-RS. Estendiamo l’esempio base introducendo le classi Request e Header così definite:

L’idea è quella di avere una request generica per tutti i servizi, che include sempre un bean Header contenente informazioni comuni a tutte le chiamate. Nel nostro esempio abbiamo inserito la proprietà sender che identifica il chiamante ed intendiamo recuperare l’header attraverso un interceptor per renderlo disponibile a tutta l’applicazione attraverso un oggetto ThreadLocal.

L’Interceptor

CXF consente la dichiarazione di un interceptor in diversi modi. Manteniamo però la natura annotation based del progetto e quindi utilizziamo l’annotazione @org.apache.cxf.interceptor.InInterceptor, che consente di intercettare la request in ingresso. Analogamente  è possibile intercettare la response del servizi utilizzando l’annotazione @org.apache.cxf.interceptor.OutInterceptor. Nella dichiarazione dell’end-point del servizio HelloWord, implementato da HelloWordImpl, introduciamo quindi l’annotazione richiesta per l’interceptor ottenendo:

In questo modo tutte le chiamate verso i servizi esposti dalla classe, ed in particolare verso il metodo geetings(), attiveranno l’interceptor HeaderInterceptor. Si noti che è anche possibile definire più interceptor attivati nella stessa invocazione del servizio.

CXF definisce una gerarchia di interceptor molto complessa a partire dall’interfaccia org.apache.cxf.interceptor.Interceptor. Nel nostro esempio utilizzeremo un PhaseInterceptor, che consente di controllare la fase di elaborazione del messaggio in cui l’interceptor è invocato, ed in particolare estenderemo la classe astratta AbstractPhaseInterceptor che ci consente di concentrare i nostri sforzi nel solo metodo di elaborazione del messaggio. Il bean HeaderInterceptor ha quindi il seguente aspetto:

Nella dichiarazione di un PhaseInterceptor è necessario definire la fase di elaborazione in cui si intende intervenire. Questo è fatto nel costruttore del bean che implementa l’interceptor. Per un elenco delle possibili fasi, sia in ingresso che in uscita al servizio, si rimanda alla documentazione ufficiale raggiungibile al link Interceptors and Phases.

Il messaggio è invece elaborato dal metodo handleMessage(), dichiarato nell’interfaccia Interceptor e che deve essere sovrascritto dal bean. Nel nostro esempio il contenuto del messaggio viene letto ciclicamente fino ad ottenere un oggetto di tipo Request, dal quale recuperiamo la proprietà header che andiamo ad inserire in un oggetto ThreadLocal, gestito dalla classe RequestContextHolder.

Codice Sorgente

Il codice sorgente dell’esempio è scaricabile qui jaxws-webapp-interceptor.

Errata Corrige

Ne progetto scaricabile manca una componente fondamentale affinché l’interceptor si attivi, ovvero la configurazione del MANIFEST.MF da inserire all’interno della cartella resources/META-INF e deve avere le dipendenze necessarie:

Inoltre nel pom.xml deve essere configurato il plug-in per la generazione del war nel seguente modo:
Per un esempio funzionante e completo si rimanda all’articolo Spring Custom Scope.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!