Sei sulla pagina 1di 5

Creare web services client con Eclipse, AXIS2 e Tomcat

Rosario Turco

In questa seconda parte esaminiamo come realizzare un client di un web service con Eclipse, Axis2 e
Tomcat.

Per testare un web service, di solito, usiamo il comodo SOAPUI, ma quando dobbiamo realizzare un
applicativo client di un web service, dobbiamo rimboccarci le maniche e farlo.

Un client è un po’ più complesso a realizzarsi rispetto alla parte server, anche perché occorre conoscere
AXIOM e le varie primitive in gioco; inoltre dobbiamo decidere se vogliamo un servizio sincrono bloccato
(usiamo solo lo stub) o uno asincrono non bloccato (oltre allo stub dobbiamo usare anche la callback).

Se usate un buon IDE è chiaro che vi semplificate la vita e aumentate la vostra velocità di sviluppo (cosa a
cui dovreste sempre mirare), diminuendo nel contempo le possibilità di errore, ma dovete sapere cosa fare
e bene.

Eclipse Helios vi da una buona mano con i suoi plug-in Axis2 e non è dedicato a nessuna piattaforma di
sviluppo particolare. Se usate Tomcat in particolare, Axis2 e Axiom sono un must per i web service, per cui
vediamo come si procede.

Se il web service da usare è esistente e attivo (sul vostro PC o su un sistema remoto), abbiamo due
possibilità sfruttare il servizio startato su una URL, che vedremo, oppure usare la WSDL fornitoci (il
procedimento è simile).

Supponiamo semplicemente che il servizio è un servizio di conversione di temperature da gradi Farenheit a


Celsius e viceversa; avremmo potuto usare il classico HelloWorld + nome della persona, o un altro servizio
classico che fa le quattro operazioni aritmetiche. Insomma qualunque cosa che ci risponda una stringa ad
esempio o anche un metodo con più input, cosa che spiegheremo dopo il caso semplice, se no dov’è il
valore aggiunto?

Supponiamo che il sorgente del web service startato sia come segue:

package wtp;

public class Converter


{
public float celsiusToFarenheit ( float celsius )
{
return (celsius * 9 / 5) + 32;
}

public float farenheitToCelsius ( float farenheit )


{
return (farenheit - 32) * 5 / 9;
}
}

1
Con Eclipse facciamo File->New->Other->Web Service->Web Service Client->Next. Su Service Definition
mettiamo la url che ci hanno comunicato del web service come in figura.

Scegliamo poi il nostro server Tomcat 6.0 o superiore, mettiamo Apache Axis2 come Web service runtime,
su Client project inseriamo il nome del progetto ad esempio Axis2WSTest o qualsiasi altro e diamo ok
ottenendo la figura.

Fate Next e lasciate al momento il valore di default. Per curiosità potreste anche generare un test case con
JUNIT, ma non è utile a scrivere il vostro client: è uno skeleton generalizzato per vedere se funziona il client,
ma non vi da i risultati.

In automatico vi escono i valori di figura e scegliamo di generare un client sia per modalità asincrona che
sincrona, anche se lo svilupperemo in modalità sincrona, mettendoci magari un timeout.

2
Fate Next e nel progetto vi ritroverete due file generati come in figura: ConverterCallbackHandler.java e
ConverterStub.java

Adesso il primo consiglio è farvi una lettura del file di stub, che è quello che permette la comunicazione
remota con il web service reale, è un proxy locale al web service remoto.

Di esso ci interessano i tipi dichiarati: la classe stessa ConverterStub, il tipoNomeMetodoRemoto che


assomiglia cioè al nome del metodo remoto, nel nostro caso CelsiusToFarenheit e il tipo della response
CelsiusToFarenheitResponse.

Ora scriviamo il Client ConverterClient.java; da Eclipse sul package wtp facciamo New->Class e come nome
classe mettiamo ConverterClient e gli facciamo generare il main e poi aggiungiamo delle righe.

package wtp;

import java.rmi.RemoteException;

import org.apache.axis2.AxisFault;

import wtp.ConverterStub.CelsiusToFarenheit;
import wtp.ConverterStub.CelsiusToFarenheitResponse;

public class ConverterClient {

public static void main(String[] args) {


final int CLIENT_TIMEOUT = (10*60*1000);
float celsiusValue = 100;

try {

ConverterStub stub = new ConverterStub();

stub._getServiceClient().getOptions().setTimeOutInMilliSeconds(CLIENT_TIMEOUT);

CelsiusToFarenheit c2f = new


ConverterStub.CelsiusToFarenheit();
c2f.setCelsius(celsiusValue);
CelsiusToFarenheitResponse res =
stub.celsiusToFarenheit(c2f);
System.out.println("Celsius : "+celsiusValue+" = "+"Farenheit
: "+res.get_return());
} catch (AxisFault e) {

3
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}

}
}

Per assegnare i valori, come vediamo, dobbiamo usare i metodi set che troviamo nello Stub, come
setCelsius.

Proviamo un attimo quello che abbiamo creato. Teniamo startato il Tomcat, su cui abbiamo dichiarato la
parte Axis2, poi facciamo selezionando il Client col tasto destro del mouse Run As->Java Application e da
console vediamo il risultato.

Io ho startato sullo stesso server Tomcat, sia il web service server che la parte client. Ovvero ho avviato
Tomcat, poi per il web service server ho selezionato il progetto e tasto destro del mouse Run As -> Run On
Server->Finish e ottenuto la prima videata del servizio attivo.

Ora starto il client, selezionando il nome del sorgente e tasto destro del mouse Run As -> Java Application
(ho scritto il main e faccio la stampa del valore ritornato: avevo chiesto 100 °C a quanti Farenheit
corrispondono). In console vedo il risultato:

Ok funziona, andiamo oltre.

4
Se ho, invece, nel web service esposto, un metodo con più “parameter” in input come faccio? E’ semplice,
nello stub troverete un metodo set<nome parameter> per ogni input. Per cui a quel punto dovrete usare la
variabile del tipoNomeMetodoRemoto (nel nostro caso c2f) e settare con essa ogni parametro cioè fare:

c2f.setCelsius(variabile_col_valore);

c2f.setFarenheit(variabile_col_valore);

etc.

Il metodo visto è sincrono/bloccato. Se avessimo usato l’asincrono non bloccato avremmo dovuto usare
anche la callback e registrare il client con la callback class.

Un esempio di completamento della callback è il seguente:


package org.example.math;

import org.example.math.MathServiceStub.AddResponse;

public class CallBack extends MathServiceCallbackHandler {


private boolean complete = false;

public void receiveResultAdd(AddResponse result) {


System.out.println("Result in Callback " + result.getAddResponse().getResult());
complete = true;
}

public boolean isComplete() {


return complete
}
}

Mentre il client potrebbe essere


public static void main(String[] args)

MathServiceStub stub

try {
stub = new MathServiceStub("http://localhost:8080/axis2/services/mathService");
MathServiceStub.Add add = MathServiceStub.Add();
MathServiceStub.MathInput input = new MathServiceStub.MathInput();
input.setX(3);
input.setY(5)
add.setAdd(input);
CallBack cb = new CallBack();
stub.startAdd(add, cb);

while(!cb.isComplete()) {
System.out.println("Do Something");
}
} catch (AxisFault e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}

Tutto chiaro? Alla prox.