Realizzare un Web Services in pochi minuti con Apache Axis

Realizzare un Web Services in pochi minuti con Apache Axis
(domenica 19 dicembre 2004) -
Viene illustrato il framework di sviluppo per i Web Service Apache Axis. Viene
inoltre mostrato come realizzare un semplice Web Service con strumenti open
source e con il linguaggio Java
- Introduzione
- L'Axis nella manica
- Il server servente
- Coding: lato server
- Il client ordina ed ottiene
- Un po' di sicurezza: ma molto poca
- Link
- Commenta l'articolo
Introduzione
I Web Services (WS) rivoluzioneranno il mondo dell'informatica grazie all'uso
del linguaggio XML: questo oramai lo abbiamo capito,
ma come facciamo allora a sviluppare WS?
Innanzitutto scegliete il vostro linguaggio di programmazione preferito:
se la vostra scelta è Java allora quasi d'obbligo è l'uso di Apache Axis su Tomcat.
Axis è il framework di sviluppo per i WS mentre Tomcat è l'application server
dove avviene l'esposizione dei WS.
L'Axis nella manica
Axis permette lo sviluppo di WS sia in Java che in
C++ ma noi ci occuperemo solo del lang di casa Sun, Java implementa gli standard:
- JAX-RPC: insomma SOAP con il classico RPC
- SAAJ: permette di manipolare il messaggio SOAP e gestire gli attachment
- tanti altri...
Axis implementa quindi il modello JAX-RPC e supporta anche SAAJ, per un
maggiore approfondimento vedi articolo precedente. Non tutto nasce però
da Apache, il prodotto iniziale è merito di IBM, che poi molto gentilmente
decise di regalare al consorzio Apache tutto il codice. Viene alla luce
quindi Apache SOAP e poi la sua evoluzione: Apache Axis.
Le caratteristiche più importandi del framework sono:
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33
- implementazione SOAP 1.1/1.2
- supporto JWS (Java Web Services): permette un facile e immediato deploy dei WS
- supporto serializzazione/deserializzazione
- implementazione WSDL
- utility WSDL2Java e Java2WSDL
- Soap Monitor e TCP Monitor: due applicazioni scritte in Java che permettono di
monitorare il traffico SOAP
- possibilità di usare tre differenti metodi per l'invocazione dei WS:
Dynamic Invocation Interface, Stub generato dal WSDL e Dynamic Proxy
I componenti di Axis sono quindi: un engine per l'elaborazione dei messaggi
SOAP, handler per la gestione dei messaggi, vari meccenismi di deploy,
serializzazione/deserializzazione, configurazione e di trasporto dei messaggi.
Il server servente
Come primo passo è necessario aver configurato Java su una macchina Linux.
E' possibile scaricarsi dal sito della Sun il pacchetto in vari formati:
l'installazione è molto semplice ed avviene tramite una wizard grafica.
Al termine dell'installazione è necessario settare le varibili di sistema
$JAVA_ HOME e $PATH, che contengono rispettivamente il percorso della
directory d'installazione di JAVA e degli esegubili, come ad es.:
export JAVA_HOME = /usr/java/jdk1.5.0
export PATH = $PATH:$JAVA_HOME/bin
Per quanto riguarda Axis è sufficiente scaricarsi il pacchetto dal sito
e scompattarlo (io consiglio sempre /opt/axis, da questo momento in poi farò
riferimento a questa directory).
L'installazione di Tomcat avviene con le modalità classiche
(compilazione o RPM, anche in questo caso considero come home di Tomcat la
directory /opt/tomcat). Esistono comodi script per l'avvio e l'arresto
dell'application server che si trovano in $CATALINA_HOME/bin.
La verifica della corretta configurazione si ottiene digitando nel
browser http://localhost:8080 e verificando la comparsa della home page Tomcat.
Axis si integra molto semplicemente con Tomcat: l'unica operazione da
eseguire è la copia della directory webapps/axis (nella home di Axis,
quindi /opt/axis/webapps/axis) all'interno di webapps (nella home di Tomcat,
quindi /opt/tomcat/webapps). Successivamente, per comodità, si possono
configurare un po' di varibili globali:
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33
export JAVA_ENDORSED_DIRS = $CATALINA_HOME/bin:
$CATALINA_HOME/common/lib:
$CATALINA_HOME/webapps/axis/WEB-INF/lib
export AXIS_HOME = /opt/axis
export AXIS_LIB=$AXIS_HOME/lib
export AXISCLASSPATH = $AXIS_LIB/axis.jar:
$AXIS_LIB/commons-discovery.jar:
$AXIS_LIB/commons-logging.jar:
$AXIS_LIB/jaxrpc.jar:
$AXIS_LIB/saaj.jar:
$AXIS_LIB/log4j-1.2.8.jar:
$AXIS_LIB/xml-apis.jar:
$AXIS_LIB/xercesImpl.jar
La variabile $AXISCLASSPATH rappresenta i riferimenti alle librerie jar
che contengono l'implementazione degli standard sui WS come SAAJ e JAX-RPC;
osservate l'ultima libreria dove è incluso il parser XML
Xerces, Java include il parser Crimson ma Apache consiglia Xerces:
entrambi funzionano adeguatamente quindi la scelta è puramente personale.
Eventualmente potreste settare un'ulteriore variabile globale $CLASSPATH
che contiene il percorso di altre librerie, io di solito copio tutti i
jar che mi servono in $CATALINA_HOME/common/lib ma ognuno può adottare il
metodo che preferisce.
In alcuni casi potrebbe essere necessario l'uso della libreria
activation.jar, che può essere scaricata comodamente dal sito della Sun.
La verifica della corretta integrazione tra Axis e Tomcat si ottiene facendo
puntare il browser http://localhost:8080/axis: dovrebbe compare la semplice
home page testuale di Axis da cui è possibile effettuare alcune operazioni.
Coding: lato server
Apache AXIS implementa, come già accennato, il nuovo standard JWS di Java
che permette di effettuare il deploy di un WS in maniera semplice e veloce.
E' sufficiente sviluppare la propria classe in Java, testarla, cambiare
l'estensione da .java e .jws e il WS è pronto: niente di più immediato.
Axis lo tratterà in maniera simile ad una JSP ossia lo compilerà e si
occuperà dell'interfacciamento con SOAP mediante la conversione automatica
SOAP-JAVA. Tale metodo ha ovviamente il pregio della semplicità a scapito
della flessibilità: è infatti impossibile decidere quali metodi esporre e
specificare conversioni specifiche tra SOAP e JAVA. Un metodo più
flessibile è l'uso dei file WSDD (Web Service Deployment Descriptor),
introdotti da Axis, ma per il primo WS l'uso del JWS è più che adeguato.
Un WS accessibile è quindi una classe Java che espone i propri metodi
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33
pubblici e non-static.
Scriviamo ora una semplice classe di esempio che controlla se un numero
è pari oppure dispari: l'esempio è ovviamente molto semplice
(direi ridicolo ma non volevo fare il solito esempio del saluto
Hello User, I'm your WS), ma potrebbe essere il primo metodo
di una classe matematica che si occupa di effettuare appunto calcoli
matematici. Il metodo pari restituisce un valore di tipo String.
public class matematica{
public String pari(int numero) {
return (numero%2)==0 ? "pari" : "dispari";
}
}
Chiamamo il file matematica.jws e copiamolo nella direcotory
$CATALINA_HOME/webapps/axis. Ora è necessario eseguire il deploy,
ovvero quella operazione che permette di rendere disponibile il nostro WS
ottenendo il file WSDL descrittore del WS.
Per ottenere questo e verifare la corretta interpretazione e compilazione
dei WS si digiti nel browser:
http://localhost:8080/axis/matematica.jws?WSDL.
Il file WSDL ottenuto è il seguente:
<?xml
version="1.0" encoding="UTF-8"?>
<wsdl:definitions
targetNamespace="http://localhost:8080/axis/matematica.jws"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://localhost:8080/axis/matematica.jws"
xmlns:intf="http://localhost:8080/axis/matematica.jws"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:message name="pariResponse">
<wsdl:part name="pariReturn" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="pariRequest">
<wsdl:part name="numero" type="xsd:int"/>
</wsdl:message>
<wsdl:portType name="matematica">
<wsdl:operation name="pari" parameterOrder="numero">
<wsdl:input message="impl:pariRequest" name="pariRequest"/>
<wsdl:output message="impl:pariResponse" name="pariResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="matematicaSoapBinding" type="impl:matematica">
<wsdlsoap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="pari">
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="pariRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://DefaultNamespace" use="encoded"/>
</wsdl:input>
<wsdl:output name="pariResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://localhost:8080/axis/matematica.jws" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="matematicaService">
<wsdl:port binding="impl:matematicaSoapBinding" name="matematica">
<wsdlsoap:address location="http://localhost:8080/axis/matematica.jws"/>
</wsdl:port>
</wsdl:service> </wsdl:definitions>
E' immediato vedere come il file sia di facile lettura, ad esempio
si possono individuare:
- wsdl:message: indicano il tipo dei dati scambiati, int in ingresso e
string in uscita
- wsdl:portType: il tipo di operazione e i parametri
- wsdl:bindings: il tipo di protocollo usato
- wsdl:service: caratteristiche del WS come l'indirizzo
Il WS è completamente realizzato ed esposto, ossia accessibile...
ma ora come possiamo interrogarlo?
Il client ordina ed ottiene
Ci sono varie tecniche di interfacciamento al WS e molte di queste usano
come informazione il file WSDL generato (stub) e reso disponibile dal
server: tali techniche non sono immediate, noi come primo esempio useremo
invece la Dinamic Invocation che non fa uso del WSDL.
Prima di tutto dovete però; armarvi di buona pazienza e, come nel server,
impostare la variabile d'ambiente $AXISCLASSPATH
Ecco il semplice codice del client:
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;
import java.net.URL;
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33
import javax.xml.rpc.ParameterMode;
public class clientMatematica {
public static void main(String[] args) throws Exception {
Integer numero= new Integer(args[0]);
String nameWS = "http://localhost:8080/axis/matematica.jws";
URL endPointWS=new URL(nameWS);
//inizializzazione WS
Service service = new Service();
Call call = (Call) service.createCall();
call.removeAllParameters();
//configurazione parametri WS
call.setTargetEndpointAddress(endPointWS);
call.addParameter("numero",XMLType.XSD_INT,ParameterMode.IN);
call.setOperationName("pari");
call.setReturnType(XMLType.XSD_STRING);
//invocazione WS
String risultato = (String)call.invoke(new Object[]{numero});
System.out.println("Il numero "+numero+" e' "+risultato);
}
}
La lettura del codice è agevole:
- istanzazione degli oggetti Call e Service
- configurazione dell'endpoint: in questo caso l'indirizzo del WS (setTargetEndpointAddress)
- indicazione tipo parametri d'ingresso (addParameter)
- indicazione del nome del metodo da invocare (setOperationName)
- indicazione tipo parametri d'output (setReturnType)
- indicazione parametri e invocazione del medoto (invoke)
- gestione del risultato
E di seguito compilazione, avvio ed output:
# javac -classpath $AXISCLASSPATH clientMatematica.java
# java -cp $AXISCLASSPATH clientMatematica 5
Il numero 5 e' dispari
Il messaggio SOAP inviato dal client al serve dovrebbe assomigliare a qualcosa di simile:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33
xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:pari xmlns:ns1="http://localhost:8080/axis/matematica.jws">
<arg0 xsi:type="xsd:int">5</arg0>
</ns1:pari>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope&gt
mentre la risposta è:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:pariResponse xmlns:ns1="http://localhost:8080/axis/matematica.jws">
<arg0 xsi:type="xsd:string">dispari</arg0&gt
</ns1:pariResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope&gt
Non commento i due messaggi SOAP per non insultare la vostra intelligenza,
infatti sono solo indicati i parametri e il WS esposto.
Tutto molto semplice, fin troppo semplice. Vi ricordo però che questa
metodologia è la meno flessibile poiché non considera il file WSDL e
quindi non permette un'automatizzazione della procedura.
L'uso del JWS, come già illustrato, ha delle limitazioni poiché si deve
disporre del codice sorgente e rende impossibili gestioni personalizzate:
un risultato maggiormente scalabile si ottiene ricorrendo al WSDD e le
utility WSDL2Java e Java2WSDL.
Un po' di sicurezza: ma molto poca
I WS presentano vari problemi di sicurezza: primo tra tutti sono
testo HTTP in grado di invocare metodi e passare inosservati attraverso
i firewall. Sono allo studio vari protocolli di sicurezza, alcuni
sono già disponibili e completamente funzionanti ma risulta difficile
applicarli ad una piccola realtà.
E' per questo che la prima generazione di WS non ha tecniche di sicurezza
ad-hoc ma usa modalità ereditate dal vecchio HTTP: ossia i tunnel SSL/TLS
over HTTP, insomma il cosiddetto HTTP-Secure (HTTPS).
Per usare HTTPS, poiché i WS risiedono su un application server,
si deve come prima cosa configurare Tomcat per accettare connessioni cifrate.
Si deve creare un certificato per il server tramite l'utility keytool di Java,
successivamente si deve configurare il web server in modo tale che
accetti connessioni https sulla porta 8443 modificando il file di
impostazioni server.xml inserendo/decommettando le seguenti righe:
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33
<!--Definea SSL Coyote HTTP Connector on port 8443 -->
< Connector port="8443"
maxThreads="150" minSpareThreads="25"
maxSpareThreads="75" enableLookups="false"
disableUploadTimeout="true" acceptCount="100"
debug="0" scheme="https"
secure="true" clientAuth="false"
sslProtocol="TLS"
&nbsp/>
La correttezza della procedura può essere verificata controllando:
https://localhost:8443/axis/matematica.jws
Ora il client deve interrogare il server WS sulla porta 8443: ciò
può avvenire in due modi differenti:
- autenticazione one-way (stile browser per intederci): solo il server ha il certificato, allora si devono riscrivere (vuoti) un
paio di metodi Java
- autenticazione two-way: il server genera un certificato anche per il client, quest'ultimo deve richiamarlo nel codice.
Ma vi sto dicendo già troppo...comunque il prossimo articolo riguarda
la sicurezza nei WS...quindi basta aspettare...insomma abbiate un po' di pazienza...
!!! Nel mentre divertitevi con Apache Axis !!!
Link
- www.webservices.org: il portale per definizione
- ws.apache.org/axis: il tool Apache Axis
- apache.tomcat.org: l'application server Tomcat
- webservices.xml.com: il portale del mitico O'Reilly
- java.sun.com: Java
http://vlain.altervista.org - public void vLAiN [rudi Verago]
Powered by Mambo
Generated: 29 September, 2016, 16:33