In questo tutorial implementeremo un semplice SOAP web service in

In questo tutorial implementeremo un semplice SOAP web service in PHP che un client Java richiamerà.
In questo modo mostreremo l'interoperabilità fra linguaggi diversi che SOAP permette di avere.
La struttura del modello client/server sarà di questo tipo:
Il client java richiede un servizio, passando eventuali parametri di input e aspetta una risposta dal server SOAP PHP.
Il client non deve necessariamente conoscere la logica dell'applicazione server, ma deve solo avere le specifiche per poter richiamare i servizi, ad esempio l'URL di dove risiedere il server, i servizi che mette a disposizione e la firma dei servizi (Parametri di input e di output).Il meccanismo della comunicazione SOAP è il seguente:
•
Client e Server comunicano tramite il protocollo SOAP.
•
Il server descrive tramite un file WSDL lo skeleton dei servizi che espone (Ovvero indica al client i parametri di Input e di Output di ogni servizio e come raggiungerli).
•
Se il client invia una richiesta SOAP valida, ovvero che segue le direttive del WSDL, allora il server manda una risposta SOAP al client contenente il risultato della chiamata effettuata dal client.
•
Se il client invia una richiesta SOAP non valida il server invia un errore o un eccezione al client.
Chiamate errate tipiche sono quelle in cui si richiama un servizio che non esiste, oppure si richiama sbagliando la cardinalità o il tipo dei parametri da passare.
La caratteristica principale del protocollo SOAP è che permette una comunicazione a client e server di diversa specie.
Si può avere ad esempio un server SOAP PHP (ma anche un server SOAP Java o .NET) a cui accedono applicazioni desktop scritte in Java o in .NET, applicazioni mobile che supportano la comunicazione SOAP e in generale, la comunicazione è possibile per qualsiasi linguaggio supporti questo tipo di protocollo che il server mette a disposizione.
Questo protocollo rende client e server indipendenti l'uno dall'altro, al server non interessa la logica dell'applicazione del client, al client non interessa la logica dell'applicazione del server, il server mette a disposizione dei servizi per eventuali client che li richiamano.
Nel nostro esempio, il nostro server metterà a disposizione del client un servizio che prende come parametri un intero positivo e restituisce la radice quadrata del parametro passato.
Configurazione dell'ambiente del client Java
Java SE ­ Versione 1.6 Axis SOAP toolkit ­ Versione 1.4
Configurazione dell'ambiente del server PHP
PHP ­ Versione 5.2
APACHE ­ Versione 2.2.17
Configurazione di SOAP nel file php.ini per evitare problemi di cache nella lettura del file wsdl:
[soap]
soap.wsdl_cache_enabled=0
soap.wsdl_cache_ttl=10
soap.wsdl_cache_limit = 5
Moduli PHP necessari:
xmlrpc
Creazione del file WSDL (Sul server)
Per prima cosa scriviamo il file WSLD che contiene le informazioni necessarie che il client deve avere per poter accedere al servizio.
ServerSoapPHP.wsdl
<?xml version="1.0" encoding="UTF­8" standalone="no"?>
<!­­ WSDL Server SOAP PHP
@author Walter russo ­­>
<definitions name="ServerSoap" targetNamespace="http://localhost/soap/Other/"
xmlns:tns="http://localhost/soap/Other/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
<!­­ Costruzione del messaggio della richiesta SOAP­­>
<message name="radiceQuadrataRequest">
<wsdl:part name="intParameter" type="xsd:integer" />
</message>
<!­­ Costruzione del messaggio della risposta SOAP­­>
<message name="radiceQuadrataResponse">
<part name="result" type="xsd:double" />
</message>
<portType name="radiceQuadrataPortType">
<operation name="radiceQuadrata">
<input message="tns:radiceQuadrataRequest" />
<output message="tns:radiceQuadrataResponse" />
</operation>
</portType>
<binding name="radiceQuadrataBinding" type="tns:radiceQuadrataPortType">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="radiceQuadrata">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" namespace="http://localhost/soap/Other/"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="literal" namespace="http://localhost/soap/Other/"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
<!­­ Descrizione del servizio radiceQuadrata ­­>
<service name="radiceQuadrataService">
<port name="radiceQuadrataPort" binding="tns:radiceQuadrataBinding">
<soap:address location="http://localhost/soap/Other/PHPSoapServer.php" />
</port>
</service>
</definitions>
Il server PHP
Il server SOAP php deve esporre il metodo per il calcolo della radice quadrata, caricare i servizi che desidera esporre e caricare il file
ServerSoapPHP.wsdl.
PHPSoapServer.php
<?php
/**
* Server SOAP di esempio che calcola la radice quadrata di un numero
* @author Walter Russo
*/
/**array delle funzioni che il server deve esporre ai client*/
$functions = array
(
"RadiceQuadrata"
);
/**
* La funzione che effettivamente viene richiamata dal client
* @param $intParameter
*/
function radiceQuadrata ($intParameter)
{
return sqrt($intParameter);
}
/**
* Funzione che include i servizi che il server espone
* @param $functions
* @param $server
*/
function addFunctions($functions,$server)
{
foreach ($functions as $function) {
//Aggiungi un nuovo servizio
$server­>addFunction($function);
}
}
/**
* Entry Point del server
* @var unknown_type
*/
//Crea Oggetto SoapServer passandogli il percorso del file wsdl.
$server= new SoapServer("ServerSoapPHP.wsdl");
//AGGIUNGI I SERVIZI
addFunctions($functions,$server );
$server­>handle();
?>
IL CLIENT JAVA
Il client java deve conoscere poche cose del server, ovvero dove risiede il server e la firma dei servizi da richiamare (Parametri di input e di output)
/**
* Client in java che richiama un webservice soap scritto in PHP.
* Il servizio richiamato restituisce la radice quadrata di un numero intero positivo
*
* @author Walter Russo
*
*/
import
import
import
import
import
import
import
java.net.MalformedURLException;
javax.xml.namespace.QName;
javax.xml.rpc.ParameterMode;
javax.xml.rpc.ServiceException;
org.apache.axis.client.Call;
org.apache.axis.client.Service;
org.apache.axis.encoding.XMLType;
public class ClientJavaSoap {
/*Uri del server */
static String soapuri = "http://localhost/soap/Other/PHPSoapServer.php";
public static Call configureService() throws ServiceException,
MalformedURLException {
Service service = new Service();
// Instanzia l'oggetto Call
Call call = (Call) service.createCall();
// setta le coordinate del server
call.setTargetEndpointAddress(new java.net.URL(soapuri));
return call;
}
public static Double testRadiceQuadrata(int value) {
try {
Call call = configureService();
call.setOperationName(new QName(soapuri, "radiceQuadrata"));
// Parametro di input
call.addParameter("intParameter", XMLType.SOAP_INTEGER,
ParameterMode.IN);
// parametro da restituire (OUTPUT)
call.addParameter("return", XMLType.SOAP_DOUBLE, ParameterMode.OUT);
int number = value;
// Costruzione dell'array da passare nella chiamata al servizio
Object[] params = new Object[] { number };
// settare il parametro di ritorno della funzione
call.setReturnType(XMLType.SOAP_DOUBLE);
// invocazione del servizio
Double ret = (Double) call.invoke(params);
// risultato della chiamata
return ret;
}
// In caso di eccezione restituiamo -1 come risultato
catch (Exception e) {
System.err.println(e.toString());
return -1.0;
}
}
public static void main(String[] args) {
int param = 99;
double result = testRadiceQuadrata(param);
System.out.print("\n Il risultato della radice quadrata di " + param
+ " è " + result);
}
}
Conclusioni
Ora non resta che provare che in tutto funzioni lanciando il client java, se tutto va a buon
fine il risultato visibile sulla consolle Java sarà il seguente:
Il risultato della radice quadrata di 99 è 9.9498743710662