MokaByte 48 - Gennaio 2001
Foto dell'autore non disponibile
di
Andrea Giovannini
SOAP e Java
Integrazione di applicazioni con Java e il nuovo protocollo SOAP
Per la realizzazione di sistemi enterprise si usano architetture basate su oggetti distribuiti come COM+, CORBA o EJB. Quando è necessario far comunicare applicazioni diverse sorgono però vari problemi ed è necessario usare appositi bridge. Le applicazioni Web devono inoltre far fronte alle limitazioni alla comunicazione imposte dai firewall.
SOAP risolve questi problemi fornendo un protocollo di RPC (Remote Procedure Call) che sfrutta HTTP come mezzo di comunicazione e XML per il formato dei dati. In questo articolo si vedranno le basi di SOAP e un esempio di codice realizzato in Java
Introduzione
SOAP (Simple Object Access Protocol) [1] è un protocollo di interazione fra componenti remoti basato su XML e HTTP. Il protocollo si compone di tre parti
 
  • un envelop che rappresenta un framework per descrivere il contenuto di un messaggio e come elaborarlo (SOAP envelope);
  • una serie di regole di codifica per rappresentare i tipi di dato definiti per l'applicazione (SOAP encoding rules);
  • delle convenzioni per rappresentare le invocazioni remote e le corrispondenti reply (SOAP RPC).


In pratica si tratta di un meccanismo di RPC in cui le richieste e le reply vengono definite mediante XML mentre il protocollo di trasporto è HTTP. L'utilizzo di XML per la descrizione di servizi distribuiti permette la massima interoperabilità.
Il protocollo vuole essere semplice ed estendibile quindi le specifiche non includono caratteristiche come garbage collection distribuita e gestione dei riferimenti remoti, tipiche dei sistemi a oggetti distribuiti.

SOAP si appoggia pesantemente sull'architettura Web in quanto sfrutta HTTP come protocollo di trasporto. Altri meccanismi di computazione distribuita, come COM+, Java RMI e CORBA, si integrano con difficoltà su Web in quanto ad esempio possono essere bloccati dai firewall.

SOAP è una proposta di varie aziende, fra le quali Microsoft, IBM e DevelopMentor, sottoposta al W3C e all'IETF per la standardizzazione. Il protocollo è alla base dell'architettura .NET di Microsoft e di Web Services di IBM. L'XML Apache Group fornisce un'implementazione Java, chiamata Apache-SOAP, basata sulla versione 1.1 del protocollo (http://xml.apache.org/soap); l'esempio presentato in questa sezione farà uso di Apache-SOAP.
 
 
 

SOAP: le basi
Un messaggio SOAP è un documento XML costituito da un envelope, un header e un body. Il SOAP envelope è obbligatorio e rappresenta il messaggio. L'header è un elemento opzionale che contiene informazioni che estendono il messaggio, relative ad esempio a gestione delle transazioni e autenticazione. Il body è un elemento obbligatorio che permette di trasmettere informazioni destinate al ricevente del messaggio. Un messaggio SOAP può infatti transitare attraverso diversi nodi intermedi. Eventuali errori vengono rappresentati dall'elemento SOAP Fault.

In SOAP sono previsti due tipi di messaggi, Call e Response. Un messaggio di tipo Call permette di invocare un servizio remoto. Si supponga ad esempio di voler richiedere la somma di due numeri a un server remoto; la richiesta in SOAP verrebbe espressa con il seguente messaggio

POST /Calculator HTTP/1.1
Host: www.mycalculator.com
Content-Type: text/xml
Content-Length: x
SOAPMethodName: My_Namespace_URI#GetSum

<SOAP:Envelope xmlns:SOAP=http://schemas.xmlsoap.org/soap/envelop"">
 <SOAP:Body>
  <m:GetSum xmlns="http://www.mycalculator.com">
   <first>3</first>
   <second>8</second>
  </m:GetSum>
 </SOAP:Body>
</SOAP:Envelope>

Le prime quattro linee sono specifiche del protocollo HTTP e indicano che si tratta di una richiesta POST inviata all'host http://www.mycalculator.com per il servizio Calculator. Il messaggio è contenuto all'interno della SOAP envelope: l'elemento GetSum contiene i parametri forniti per il servizio, in questo caso due numeri da sommare individuati dagli elementi first e second.
I messaggi Response contengono il risultato dell'elaborazione del servizio. Il messaggio Response corrispondente alla richiesta precedente sarebbe

HTTP/1.1 200 OK
Content-Type: text/xml
Content-Length: x

<SOAP:Envelope xmlns:SOAP=http://schemas.xmlsoap.org/soap/envelop"">
 <SOAP:Body>
  <m:GetSumResponse xmlns="http://www.mycalculator.com">
   <return>11</return>
  </m:GetSumResponse>
 </SOAP:Body>
</SOAP:Envelope>

In questo caso la SOAP-envelope contiene il risultato dell'elaborazione come valore dell'elemento return.

Il modello a oggetti di Apache-SOAP viene esposto dal package org.apache.soap.rpc. Il client che vuole usare un servizio remoto utilizza l'oggetto Call mediante il quale specifica il nome del metodo, l'ID  e i parametri. Una volta impostato l'oggetto Call è possibile invocarne il metodo 
invoke(URL url, String SOAPActionURI) nei cui parametri si indicano rispettivamente l'URL in cui si trova il componente che fornisce il servizio e l'header della richiesta.
Il metodo invoke() restituisce un oggetto Response che contiene la risposta al servizio richiesto oppure una segnalazione di errore.

Apache-SOAP supporta i protocolli HTTP e SMTP. Se usato su HTTP si ha il seguente processo di funzionamento

  • il client esegue un POST di un SOAP-envelope al server;
  • questo a sua volta costruisce un oggetto Call, localizza l'oggetto destinatario basandosi sull'object ID, verifica il nome del metodo e quindi chiama il metodo invoke() sull'oggetto;
  • il metodo invoke() restituisce un oggetto Response da cui il server estrae le informazioni da inserire nel messaggio response da inviare al client.

 

Un esempio completo
Si vedrà ora un esempio di servizio esposto via SOAP. Si realizzerà in Java un semplice servizio di somma remota come nell'esempio precedente. Sia il client che il server verranno implementati in Java per ragioni 'didattiche'. Si noti che potrebbero essere realizzati in qualsiasi linguaggio per il quale esista una implementazione di SOAP, come ad esempio Perl o linguaggi COM-enabled in ambiente Microsoft.

Segue ora il codice, molto semplice, del server che esegue la somma

public class MyCalculator {

 public static int getSum(int arg1, int arg2) {
  return (arg1 + arg2);
 }

}

Per fare in modo che il servizio precedente sia visibile via Apache-SOAP è necessario scrivere un deployment descriptor in XML per la classe precedente

<?xml version="1.0"?>

<n:service xmlns:n="http://xml.apache.org/xml-soap/deployment"
id="urn:xml-soap-demo-mycalculator">
 <n:provider type="java"
    scope="Application"
    methods="getSum">
  <n:java class="MyCalculator" static="true"/>
 </n:provider>
</n:service>

Una volta installato Apache-SOAP è possibile eseguire il deploy del servizio. Questo può essere fatto attrraverso un apposita pagina Web oppure da linea di comando. 

Il seguente codice mostra impostare l'invocazione del servizio di somma. Per semplicità è stata tralasciata qualsiasi gestione degli errori.

 Call call = new Call();
 call.setTargetObjectURI("urn:xml-soap-demo-mycalculator");
 call.setMethodName("getSum");
 call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
 
 Vector parms = new Vector();
 parms.addElement(new Parameter("first", int.class, 3, null));
 parms.addElement(new Parameter("second", int.class, 8, null));

 call.setParams(parms);
 URL url = new URL("http://localhost:8080/soap/servlet/rpcrouter");
 Response response = call.invoke(url, "");

 Parameter result = response.getReturnValue();
 System.out.println("Il risultato è " +
  ((Integer)result.getValue()).intValue());
 

Conclusioni
SOAP è un passo molto importante verso l'integrazione di sistemi eterogenei e offre i grandi vantaggi della semplicità: non esiste infatti una API alla quale debbano conformarsi le implementazioni del protocollo. L'implementazione in Java fornita dall'Apache Group permette di rendere i programmi Java interoperabili via SOAP e si è dimostrata molto semplice da usare. I sorgenti dell'esempio mostrato sono disponibili per il download qui.
 
 
 

Riferimenti
[1] - Le specifiche su SOAP del W3C: http://www.w3c.org/soap;

 

Vai alla Home Page di MokaByte
Vai alla prima pagina di questo mese


MokaByte®  è un marchio registrato da MokaByte s.r.l.
Java® è un marchio registrato da Sun Microsystems; tutti i diritti riservati
E' vietata la riproduzione anche parziale
Per comunicazioni inviare una mail a
mokainfo@mokabyte.it