Spring e integrazione

II parte: Integrazione di Web Servicesdi

Spring permette di "esporre" i propri servizi sotto forma di web services basati sullo standard JAX-RPC e anche di accedere a generici web services in maniera trasparente dal punto di vista del codice client. Si tratterà come sempre di gestire la configurazione di Spring, in modo che quest‘ultimo "lavori" per noi dietro le quinte per consentirci un accesso ai servizi remoti alla stregua dei componenti locali.

Introduzione

Integrare delle funzionalità  esterne all‘ambito "locale" della propria applicazione è una necessità  molto comune oggigiorno. L‘ambiente in cui particolari servizi vivono può essere più o meno esteso. Può essere circoscritto a una singola applicazione, nel caso di Java una singola Java Virtual Machine, a una rete locale, a una rete geografica o nella prospettiva più larga a Internet. Le tecnologie utilizzate per "distribuire" dei servizi in uno di questi ambiti sono le più varie. Il fattore comune a  queste tecnologie è quello di utilizzare un insieme di regole atto all‘esecuzione di procedure remote, che si può sintetizzare nella sigla RPC (Remote Procedure Call). Java fornisce un suo protocollo per l‘RPC, denominato RMI (Remote Method Invocation), che costituisce tra l‘altro  la base per la tecnologia EJB (Enterprise Java Beans). L‘uso di RMI e della tecnologia EJB ha senso generalmente per reti locali, e normalmente lo scenario è quello di distribuire i componenti applicativi in un nodo specifico accessibile dai componenti di frontend. Rendere i propri servizi accessibili in Internet implica invece utilizzare come canale di comunicazione il protocollo HTTP, dato che esso permette di attraversare le protezioni firewall delle varie reti, presupposto per avere delle funzionalità  integrabili con degli standard globali e perfettamente "delocalizzate".

Esistono alcune soluzioni che implementano l‘RPC utilizzando l‘HTTP, come per esempio l‘Hessian, ma lo standard accettato universalmente oramai è il protocollo SOAP, basato su XML. I servizi basati su SOAP sono chiamati web services e nel mondo Java la tecnologia che implementa l‘RPC basato su SOAP è la JAX-RPC. Spring fornisce un suo supporto per esporre e per integrare web services che dietro le quinte utilizza appunto lo standard JAX-RPC. Nel prossimo paragrafo verrà  spiegato come esporre delle funzionalità  sotto forma di web services, mentre nel successivo come accedere nella propria applicazione basata su Spring a dei generici web services "pubblicati" in un qualche nodo su Internet.


Distribuire dei servizi

Immaginiamo di avere la seguente  interfaccia:

public interface MyService {
 public void doSomething();
}

e la sua corrispettiva remota, che estende l‘interfaccia Remote di RMI

public interface RemoteMyService extends Remote {
 public void doSomething() throws RemoteException ;
}

Quest‘ultima è necessaria perchà© Spring utilizza JAX-RPC per supportare i web services, e quest‘ultima tecnologia è basata sul protocollo RMI. Per esporre questa interfaccia come servizio web dobbiamo utilizzare un‘estensione della classe ServletEndpointSupport che implementi l‘interfaccia remota RemoteMyService. L‘implementazione effettiva è delegata al bean myService che implementa invece l‘interfaccia "locale", configurato nell‘ApplicationContext di Spring.

public class MyServiceEndpoint extends ServletEndpointSupport implements RemoteMyService {
 private MyService myServ;
 
 protected void onInit() {
  this. myServ = (MyService) getWebApplicationContext().getBean("myService");
 }
 
 public void doSomething() throws RemoteException {
  myServ.doSomething();
 }
}

Perchè l‘ApplicationContext sia disponibile la classe deve essere distribuita nella stessa web application sulla quale è in esecuzione Spring. Se si utilizza Axis, occorrerà  configurare la servlet AxisServlet nel web.xml e la classe MyServiceEndpoint nel file server-config.wsdd.

Accedere ai servizi

La classe JaxRpcPortProxyFactoryBean permette di ottenere, attraverso le consuete funzionalità  AOP, un proxy associato al servizio web al quale si vuole accedere. Ecco il frammento di configurazione necessario a ottenere un proxy del servizio RemoteMyService:


     

La proprietà  serviceInterface è l‘interfaccia remota del servizio, la wsdlDocumentUrl è il percorso del descrittore del servizio, mentre namespaceUri è l‘URL del servizio. Possiamo a questo punto configurare un componente client al quale "iniettiamo" il riferimento al proxy precedentemente definito:


 ...
 

Di seguito l‘implementazione del componente client:

public class MyClient {
 private RemoteMyService service;
 
 public void setService(RemoteMyService service) {
  this.service = service;
 }
 
 public void foo() {
  try {
   service.doSomething();
  } catch (RemoteException ex) {
   ...
  }
 }
}

Come si vede nell‘implementazione siamo costretti a gestire un‘eccezione di tipo RemoteException. Possiamo evitare questo fornendo in configurazione in aggiunta all‘interfaccia remota la corrispondente interfaccia locale (che non estende la Remote). In questo modo Spring tradurrà  la RemoteException nell‘eccezione RemoteAccessException che essendo di tipo "Runtime" non necessita di essere gestita, a meno che non lo si voglia.


 
 esempio.MyService
 

 
 esempio.RemoteMyService
 

 ...

L‘implementazione del client in questo caso diventa:

public class MyClient {
 private MyService service;
 
 public void setService(MyService service) {
  this.service = service;
 }
 
 public void foo() {
  service.doSomething();
 }
}

E in quest‘ultimo caso si vede come sia possibile accedere alle funzionalità  del servizio remoto alla  stregua di un qualsiasi componente locale.

Conclusioni

Si è scelto in questo articolo di esporre l‘integrazione di generici web services in un applicativo Spring. Questo perchà© i servizi web sono la tecnologia più diffusa e utilizzata per distribuire servizi in Internet. Tuttavia, Spring offre un supporto anche per l‘RMI e per altre tecnologie mirate al generico concetto di Remote Procedure Call, oltre che alla tecnologia EJB. Nel prossimo articolo verrà  trattato il caso degli EJB mentre per le altre tecnologie (RMI, Hessian ecc...) si consiglia di consultare la documentazione di riferimento.


Riferimenti

[1] "Spring Reference" 2.0
http://www.springframework.org/

[2] Craig Walls - Ryan Breidenbach, "Spring in Action", Manning, 2005

Condividi

Pubblicato nel numero
118 maggio 2007
Mario Casari si è laureato in Fisica a Cagliari. Ha lavorato come progettista e sviluppatore soprattutto in ambito J2EE per diverse e importanti realtà italiane. Attualmente sta approfondendo le tematiche di utilizzo di Spring in progetti per la pubblica amministrazione.
Articoli nella stessa serie
Ti potrebbe interessare anche