Una delle cose che i programmatori Java invidiano ai loro colleghi che utilizzano .net sono le annotazioni, un modo per marcare classi o metodi per indicare funzionalità speciali. Con le nuove versioni di Java (1.6 in particolare) è possibile utilizzare le annotazioni anche in questo linguaggio e nel nostro caso le sfrutteremo per la creazione di un servizio web di esempio con J2SE6.
Ci accontenteremo di scrivere un server che abbia tre semplici metodi. Il servizio in un applicazione reale dovrebbe essere esposto tramite un application server, ma per i nostri scopi andrà benissimo farlo partire direttamente. Se volessimo veramente utilizzare un application server dovremmo anche utilizzare il tool wsgen sulla classe compilata per generare le classi necessarie all’integrazione del nostro server.
Iniziamo dal server: scriviamo una classe ‘Prova’ e la marchiamo con l’attributo @WebService. Per ogni metodo che vogliamo esporre utilizziamo l’annotazione @WebMethod. Ci limiteremo ad utilizzare tipi di dato semplici come parametri e scriveremo tre metodi, uno che accetta e ritorna un numero, uno che che fa altrettanto ma utilizzando una stringa ed uno che ritorna un array di stringhe. Tanto per restare sul concreto ecco uno stralcio
@WebService
public class Prova {
@WebMethod
public String getMyStringMessage(String InStr) {
return InStr + " ciao";
}
Possiamo compilare la classe e mandarla in esecuzione attraverso il metodo publish di un Endpoint che creiamo specificando l’uri a cui sarà raggiungibile, http://localhost:8084/prova nel caso specifico.
Per quanto riguarda i client ne scriveremo uno in Java ed uno in Ruby, tanto per testarne la compatibilità.
Cominciamo da quello Java: per prima cosa generiamo le classi stub con l’utility wsimport attraverso la definizione del WSDL messa a disposizione dal server stesso all’indirizzo indicato aggiungendo il postifisso ‘?WSDL’
wsimport -keep -d ./buildclient http://localhost:8084/prova/Prova?WSDL
Lo stub agirà come proxy del server, trasmettendogli i parametri e ricevendone i risultati. Nella scrittura del client dichiariamo una referenza al webservice attraverso l’annotazione @WebServiceRef in cui specifichiamo l’uri del servizio cui accederemo, creiamo il proxy utilizzando le classi create con l’azione di wsimport citato in precedenza e da qui in poi possiamo chiamarne tranquillamente i metodi. Per quello che riguarda il client Ruby, scritto in due modi diversi, faremo tutto in dinamico, come normale per questo linguaggio.
Classe server:
package prova;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import javax.jws.WebMethod;
@WebService public class Prova {
@WebMethod
public double getArea(double r)
{
return java.lang.Math.PI * (r * r);
}
@WebMethod
public String getMyStringMessage(String InStr)
{
return InStr + " ciao";
}
@WebMethod
public String [] getStringArray()
{
String [] retValue = new String [2] ;
retValue[0] = "A";
retValue[1] = "B";
return retValue ;
}
public static void main(String[] args)
{
Endpoint e = Endpoint.create(new Prova());
e.publish("http://127.0.0.1:8084/prova");
try
{
Thread.sleep(300000);
} catch (InterruptedException ex)
{
}
e.stop();
}
}
Il client (semplificato) in Java:
service = new ProvaService();
Prova provaProxy = service.getProvaPort();
double result = provaProxy.getArea(1.0);
System.out.println(result);
Quello (semplificato) in ruby:
require 'soap/wsdlDriver'
wsdl_url = "http://localhost:8084/prova?WSDL"
soap = SOAP::WSDLDriverFactory.new( wsdl_url ).create_rpc_driver
result = soap.getArea(:arg0=>1.0)
puts "getArea: #{result.return}"
Nell’archivio, che trovate a questo indirizzo, i sorgenti ed i comandi per compilare, mandare in esecuzione server e client.
