4.  Web Service

Abbiamo visto finora come http (trasporto) e xml (data representation) possano essere intuitivamente usati per realizzare applicazioni web. Queste semplici modalità applicative possono essere utilizzate per sviluppare applicazioni ad hoc, ma non sono sufficienti ad indirizzare gli aspetti di interoperabilità tra applicazioni sviluppate indipendentemente.

È questo l'obiettivo dei Web Services, un insieme di architetture e specifiche condivise finalizzato a risolvere i problemi di interoperabilità nella cooperazione applicativa.

4.1. Il Protocollo SOAP

Abbiamo presentato nella parte introduttiva del corso che esistono più linguaggi e protocolli utilizzabili per la realizzazione di applicazioni di tipo web services. In questo corso faremo riferimento al linguaggio XML ed al protocollo SOAP, ma tenendo ben presente che la maggior parte dei concetti sono completamente interscambiabili passando ad altre tecnologie come il linguaggio JSon ed il protocollo REST.

SOAP (Simple Object Access Protocol) è un protocollo basato su XML per lo scambio d'informazioni in un ambiente distribuito e definisce un formato comune per trasmettere dati tra client e service. SOAP prevede l'imbustamento dei contenuti applicativi da scambiare all'interno di un formato di busta XML ed e' indipendente dal protocollo di trasporto utilizato per la consegna dei messaggi, che teoricamente potrebbe anche avvenire off-line.

Il namespace degli elementi SOAP è http://www.w3.org/2001/12/soap-envelope.

L'elemento base di un messaggio SOAP è il SOAP Envelope.

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
        ...

</soap:Envelope>
            

L'Envelope ha due figli: l'Header, opzionale, e il Body, obbligatorio.

L'elemento opzionale SOAP Header estende il messaggio e contiene metadati, informazioni utili al processamento del messaggio, come ad esempio l'identità dell'utente, informazioni riguardo la cifratura del documento, o informazioni per il routing del messaggio.

<?xml version="1.0"?>
<soap:Envelope
    xmlns:soap="http://www.w3.org/2001/12/soap-envelope">

    <soap:Header>
        <myHeader soap:actor="..." soap:mustUnderstand="...">
            ...
        </myHeader>
    </soap:Header>
    
    <soap:Body ...>
        ...
    </soap:Body>
</soap:Envelope>
            

Un elemento dell'Header può avere alcuni attributi speciali:

  • MustUnderstand: Talvolta alcuni header devono essere processati affinchè l'applicazione possa procedere oltre. Si consideri ad esempio l'header contenente le informazioni di cifratura del messaggio. Se non viene processato (e quindi il messaggio rimane cifrato) il processamento non può andare avanti. Per indicare che un header DEVE essere analizzato o il processamento interrotto si usa l'attibuto MustUnderstand settandolo a "1" (di default è "0").

  • Actor: Un messaggio SOAP può viaggiare dal mittente al destinatario attraversando differenti endpont lungo il percorso. Non tutti gli header del messaggio sono necessariamente indirizzati al destinatario finale, ma anche a nodi intermedi. L'attributo opzionale actor serve appunto a specificare l'endpoint al quale è indirizzato l'elemento.

Il SOAP Body, obbligatorio, infine contiene i dati veri e propri del messaggio, chiamato Payload.

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
    <soap:Body xmlns="http://www.bank.org/ns">
        <pagamento>
            <da>cliente</da>
            <a>shop</a>
            <importo>100</importo>
        </pagamento>
    </soap:Body>
</soap:Envelope>
            

Il livello di messaggio è indipendente dal livello di trasporto, quindi la busta SOAP può essere impacchettata per essere inviata via HTTP, SMTP, etc. , ma la struttura e il contenuto della busta SOAP rimarrà immutato.

4.2. WSDL

Finora abbiamo visto come modellare (XSD) i messaggi scambiati dalle applicazioni, ma gli aspetti quali l'indirizzo fisico del servizio, le operazioni supportate, tipologia dei messaggi per ogni operazione risultano ancora cablati nelle applicazioni. Il Web Service Definition Language (WSDL) è un linguaggio basato su XML per specificare tali aspetti dei servizi. Mediante WSDL può essere quindi descritta l'interfaccia pubblica di un Web Service fornendo le informazioni necessarie per poter interagire con un determinato servizio: un "documento" WSDL contiene infatti, relativamente al Web Service descritto, informazioni su:

  • cosa può essere utilizzato (le "operazioni" messe a disposizione dal servizio);

  • come utilizzarlo (il protocollo di comunicazione da utilizzare per accedere al servizio, il formato dei messaggi accettati in input e restituiti in output dal servizio ed i dati correlati) ovvero i "vincoli" (bindings in inglese) del servizio;

  • dove utilizzare il servizio (cosiddetto endpoint del servizio che solitamente corrisponde all'indirizzo - in formato URI - che rende disponibile il Web Service)

Il WSDL puo' essere suddiviso tra definizione logica e concreta. La prima descrive le interfacce, le operazioni ed i messaggi, mentre la seconda definisce il trasporto, il binding e gli endpoint. La struttura principale del WSDL apparirà grossomodo così

<wsdl:definitions 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    
    <!-- abstract definitions -->            
    
    <wsdl:types>
        ....
    </wsdl:types>
    
    <wsdl:message>
        ....
    </wsdl:message>
    
    <wsdl:portType>
        ....
    </wsdl:portType>
    
    <!-- concrete definitions -->            
    <wsdl:binding>
        ....
    </wsdl:binding>
    
    <wsdl:service>
        ....
    </wsdl:service>

</wsdl:definitions>
            

Vediamo come costruire un WSDL che descriva il comportamento della servlet che abbiamo implementato. Per adesso possiamo dire che il nostro servizio espone un'operazione che riceve i dati di un'ordine come messaggio XML/SOAP su HTTP, senza fornire risposta SOAP al client.

4.2.1. Types

Il primo passo per la costruzione di un documento wsdl di un Web Service è quello di definirsi i tipi degli elementi in esso contenuti. Abbiamo già definto lo schema XSD di messaggio di ordine:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
    <xs:complexType name="ordineType">
        <xs:sequence maxOccurs="unbounded">
            <xs:element name="articolo" type="articoloType"/>
        </xs:sequence>
    </xs:complexType>
    
    <xs:complexType name="articoloType">
        <xs:sequence>
            <xs:element name="nome" type="nomeType"/>
            <xs:element name="quantita" type="integer"/>
        </xs:sequence>
    </xs:complexType>
    
    <xs:simpleType name="nomeType">
        <xs:restriction base="xs:string">
            <xs:pattern value="[A-Za-z]{10}"/>
        </xs:restriction>
    </xs:simpleType>
        
</xs:schema>
            

Importiamolo e aggiungiamo i tipi mancanti per l'operazione di notifica

[Nota] Nota
<wsdl:definitions 
   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:ord="http://www.rivenditore.org/ordine"
   targetNamespace="http://www.rivenditore.org/rivenditore"
                    
    <wsdl:import namespace="http://www.rivenditore.org/ordine" location="submitOrdine.xsd" />
 
    <wsdl:types>
        <xsd:schema targetNamespace="http://www.rivenditore.org/ordine"
           <xsd:element name="ordine" type="ordineType"/>
        </xsd:schema>
    </wsdl:types>
    
    ...

</wsdl:definitions>
            

4.2.2. Messages

Descritti i tipi, possiamo definire i messaggi scambiati. Il nostro servizio ha un solo messaggio SOAP scambiato, quello di consegna dell'ordine.

<wsdl:definitions 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.rivenditore.org/ordine" ...>
    
   <wsdl:types> ... </wsdl:types>
   
   <wsdl:message name="ordineMessage">
      <wsdl:part name="ordine" element="ele:ordine"/>
   </wsdl:message>
   
</wsdl:definitions>
            

Il passo successivo sarà definire le interfacce. L'elemento portType definisce un gruppo di operazioni. Il nome portType è sviante ci riferiremo a questo elemento spesso con il nome "interfaccia". Ogni wsdl:operation dell'interfaccia contiene una combinazione di elementi wsdl:input e wsdl:output e opzionalmente un wsdl:fault. L'ordine di questi elementi definisce il Message Exchange Pattern (MEP) dell'operazione.

MEP wsdl:operation
Request-Response

<wsdl:input ..>

<wsdl:output ..>
OneWay <wsdl:input ..>
Solicit-Response

<wsdl:output ..>

<wsdl:input ..>
Notification <wsdl:output ..>

Tabella 5. Message Exchange Pattern


[Avvertimento] Avvertimento

La specifica WS-Interoperability fornisce una serie di line guida per garantire una maggiore interoperabilità tra diverse piattaforme, sistemi operativi e linguaggi di programmazione. Una di queste regole dice di non utilizzare i MEP Solicit-Response e Notification.

Come detto in precedenza, l'operazione esposta dal nostro servizio prevede di ricevere un messaggio contenente un ordine, ma di non inviare messaggi SOAP di risposta, quindi un MEP di tipo Oneway. Vediamo come descrivere tale operazione.

<wsdl:definitions 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.rivenditore.org/ordine" ...>
    
    <wsdl:types> ... </wsdl:types>
    
    <wsdl:message> ... </message>
    
    <wsdl:portType name="ordineInterface">
    
        <wsdl:operation name="ordine">
            <wsdl:input message="ord:ordineMessage"/>
        </wsdl:operation>
        
    </wsdl:portType> 

</wsdl:definitions>
            

L'interfaccia è sempre considerata astratta da momento che non sa come saranno rappresentati i messaggi "sul cavo" finchè non sarà definito il binding che specifica, tra le altre cose, il protocollo di trasporto (nel nostro caso HTTP).

4.2.3. Binding

L'elemento wsdl:binding descrive i dettagli concreti per utilizzare una particolare interfaccia (portType) con uno specifico protocollo. La struttura di base dell'elemento binding è la seguente:

<wsdl:definitions .... >
    <wsdl:binding name=".." type=".."> 
        
        <wsdl:operation name=".."> 
           
           <wsdl:input name=".." > 
               ..
           </wsdl:input>
           <wsdl:output name=".." > 
               ..
           </wsdl:output>
           <wsdl:fault name=".."> 
               ..
           </wsdl:fault>
           
        </wsdl:operation>
    </wsdl:binding>
</wsdl:definitions>
                

L'attributo name, come per gli altri elementi, specifica un nome per riferirsi al binding nel resto del documento. Il type deve specificare un portType precedentemente definito. Nel nostro esempio possiamo inserire un binding chiamato ordineInterfaceBinding per l'interfaccia ordineInterface:

<wsdl:definitions 
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.rivenditore.org/ordine" ...>
   ...
    <wsdl:binding name="ordineInterfaceBinding" type="ordineInterface">
        ... 
        <wsdl:operation name="ordine">
            ... 
            <wsdl:input>
                ... 
            </wsdl:input>
        </wsdl:operation>
    </wsdl:binding>
    ...
</wsdl:definitions>
                

L'elemento wsdl:binding è generico. Definisce solamente il framework per descrivere i dettaggli di binding. Questi dettagli sono forniti utilizzando degli elementi estensivi. Le specifiche WSDL forniscono alcuni elementi predifiniti per descrivere il binding SOAP, anche se sono in un diverso namespace (http://schemas.xmlsoap.org/wsdl/soap/). Vediamo come fare un SOAP/HTTP binding per la nostra interfaccia:

<wsdl:definitions
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.rivenditore.org/ordine" ...>
   ...
  <wsdl:binding name="ordineInterfaceBinding" type="ordineInterface">
       <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
       <wsdl:operation name="ordine">
          <soap:operation soapAction=""/>
          <wsdl:input>
             <soap:body use="literal"/>
          </wsdl:input>
       </wsdl:operation>
   </wsdl:binding>
   ...
</wsdl:definitions>

l'elemento soap:binding indica lo stile usato per la rappresentazione del messaggio (i valori possibili sono document o rpc) rispetto al protocollo di trasporto richiesto (HTTP nel nostro caso). L'elemento soap:operation definisce il valore dell'header HTTP SOAPAction. Infine l'elemento soap:body descrive come i part del messaggio devono essere serializzati all'interno del messaggio (valori possibili literal o encoded).

Maggiori informazioni su queste caratteristiche sono presentate nella lezione sui web services.

4.2.4. Services

L'elemento wsdl:service definisce una collezione di porte, o endpoint, che espone un particolare binding:

<wsdl:definitions .... >
    <wsdl:service name="..."> 
        <wsdl:port name="..." binding="..."> 
           ...
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

Per ogni porta dobbiamo fornire un nome da utilizzare come riferimento ed un binding tra quelli definiti in precedenza. Poi possiamo aggiungere elementi estensivi che definiscono i dettagli per l'indirizzamento specifici del binding.

<wsdl:definitions 
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://www.rivenditore.org/ordine" ...>
   ...
   <wsdl:service name="ordineService">
      <wsdl:port name="ordineInterfaceEndpoint" binding="ord:ordineInterfaceBinding">
         <soap:address location="http://www.rivenditore.org/ordine"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>

4.2.4.1. WSDL Validation

Una volta completato il wsdl possiamo verificarne la correttezza sintattica e l'aderenza alle specifiche WS-I. Ci sono vari tools utilizzabili a questo scopo, come quello distribuito con CXF, il Web Services Framework parte del progetto Apache, che utilizzeremo come base per le nostre attività di esercitazione. Per eseguire la validazione con CXF basta invocare il comando:

wsdlvalidator service.wsdl

4.3. Web Service in Java

Esistono diversi approcci per implementare un Web Service, anche in funzione degli specifici framework e linguaggi utilizzati. La principale differenza comunque risiede nella scelta di scrivere la logica applicativa dei propri servizi (lato client e server) in maniera trasparente rispetto al linguaggio di programmazione utilizzato, ad esempio invocando ed implementando direttamente metodi delle classi applicative, o piuttosto con una visibilità esplicita dei messaggi scambiati, utilizzando quindi approsite API per la gestione dei messaggi SOAP, e parser xml per la gestione dei contenuti applicativi dei messaggi.

Nel seguito di questa sezione vedremo come usare questi due approcci usando il linguaggio Java.

4.3.1. Approccio centrato su classi Java

Ci sono due possibilità per scrivere applicazioni di questo tipo:

  • si scrive il servizio come una classe Java, si usa JAX-WS per l'annotazione della classe e si genera poi il WSDL del servizio, tramite appositi tool (es: Java2WSDL in CXF);

  • nel caso in cui sia già disponibile il WSDL del servizio, si può invece generare le classi java da usare per la sua implementazione: gli "stub" per il lato client e gli "skeleton" sul lato server.

In entrambi questi casi, è quindi possibile usare i Web Services in maniera trasparente dal linguaggio di programmazione, in modo tale che per ogni operazione supportata dal servizio sia semplicemente necessario invocare un metodo java sul lato client e implementare un metodo java sul lato server.

4.3.1.1. Uso di WSDL2Java

Il JAX-WS fornisce un mapping completo dalla definizione dei Web Service in WSDL alle classi Java che implementano quel servizio. L'interfaccia logica, definita dall'elemento wsdl:portType, e' mappata in un service endpoint interface (SEI). Ogni tipo complesso definito in un WSDL viene mappato in classi Java che seguono il mapping definito dalla specifica Java Architecture for XML Binding (JAX-B). L'endpoint definito dall'elemento wsdl:service viene generato in una classe Java usata dai fruitori per accedere agli endpoint che implementano il servizio.

Il tool wsdl2java automatizza la generazione di questo codice. Inoltre fornisce opzioni per la generazione del codice di partenza per l'implementazione del servizio ed altre funzionalita'.

E' possibile generare il codice necessario allo sviluppo del servizio con il seguente comando

wsdl2java -ant -impl -server -d outputDir myService.wsdl

Le opzioni hanno le seguenti funzioni:

  • L'argomento -ant genera un makefile per Ant, chiamato build.xml per eseguire e compilare l'applicazione

  • L'argomento -impl genera una classe che implementa ogni portType specificato dal WSDL

  • L'opzione -server genera un semplice main() per l'esecuzione del servizio come applicazione stand alone

  • L'opzione -d specifica la directory dove posizionare il codice generato

  • myService.wsdl e' il WSDL del servizio da implementare

Una volta eseguito il comando ci troveremo una serie di classi generate:

  • portTypeName.java il SEI. Questo file contiene l'interfaccia che il servizio implementa.

  • serviceName.java l'Endpoint. Questa classe verra' usata dai fruitori per effettuare richieste al servizio.

  • portTypeNameImpl.java lo Skeleton. Qeusta classe e' l'implementazione del servizio.

  • portTypeName_portTypeNameImplPort_Server.java un semplice main() che consente il deploy del servizio in un server stand alone.

4.3.1.2. Uso di Java2WSDL

L'altro approccio per sviluppare Web Service e' quello che prevede lo sviluppo del codice Java annotato in standard Jax-WS e di li generarne il WSDL. Vediamo un esempio. Cominciamo dal SEI:

public interface QuoteReporter{
      public Quote getQuote(String ticker);
}

ed un esempio di implementazione:

import java.util.*;

public class StockQuoteReporter implements QuoteReporter
{
  ...
public Quote getQuote(String ticker)
  {
    Quote retVal = new Quote();
    retVal.setID(ticker);
    retVal.setVal(Board.check(ticker));[1]
    Date retDate = new Date();
    retVal.setTime(retDate.toString());
    return(retVal);
  }
}

Non rimane che annotare il codice con le annotazioni fornite dallo standard JAX-WS e fornire le seguienti informazioni

  • Il target namespace del servizio

  • La classe che racchiude il messaggio di richiesta

  • La classe che racchiude il messaggio di risposta

  • Se l'operazione e' di tipo Oneway

  • Il tipo di stile di Binding

  • Il nome della classe usata per le eccezioni

  • Il namespace dei tipi usati dal servizio

[Nota] Nota

Molte annotazioni hanno valori predefiniti, ma specificare completamente ogni dettaglio del servizio fornisce un maggior controllo sul WSDL generato e ne migliora l'interoperabilita'.

Ecco alcune delle annotazioni introdotte dalla specifica Jax-WS.

  • @XmlAccessorType: Con questa annotazione specifichiamo quali campi o proprieta' devono essere serializzati. Il valore FIELD indica che vanno serializzati tutti i campi pubblici e privati.

  • @XmlType Mappa una classe al un tipo XML Schema. Se il tipo e' complesso della specie xs:all o xs:sequence si puo' specificare gli elementi inclusi e il loro ordine con la proprieta' propOrder()

  • @XmlElement: Indica che il campo va serializzato e permette di specificarne il nome locale ed il namespace.

  • @XmlSchemaType: Mappa un tipo Java ad un tipo semplice predefinito.

  • @WebService (Required): Specifica che il metodo seguente e' l'implementazione di un endpoint.

    • name: il nome del wsdl:portType

    • targetNamespace: il namespace del WSDL e degli elementi generati (salvo diversamente imposto dalee regole di mapping di JAXB).

    • serviceName: il nome del wsdl:service

    • portName: il wsdl:portName

  • @SOAPBinding: indica il tipo di binding. Di default utilizza il Wrapped.

  • @WebResult: Indica il nome dell'elemento della risposta. Se non e' specificato utilizza [nomeoperazione]Response

  • @Oneway: Indica che il metodo e' di tipo Oneway.

Per una lista esaustiva con utili esempi di utilizzo, consultare le specifiche.

import javax.jws.*;
@WebService(targetNamespace = "http://www.rivenditore.org/Ordine", name = "OrdineInterface")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface OrdineInterface {
    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    @Oneway
    @WebMethod(operationName = "Notifica")
    public void notifica(
        @WebParam(partName = "parameter", name = "notifica", targetNamespace = "http://www.rivenditore.org/ordiniElements")
        java.lang.String parameter);
    ...
}

Una volta terminata l'implementazione e' possibile verificarne la bonta' generando il WSDL associato con l'apposito comando java2wsdl

4.3.2. Approccio centrato su messaggi SOAP

Abbiamo visto nella sezione precedente come realizzare servizi web in maniera piu' o meno trasparente rispetto ai linguaggi di programmazione utilizzati. In alcuni casi pero' questo puo' non essere conveniente, ma si puo' preferire agire direttamente sui documenti xml contenuti nei messaggi, anziche' essere costretti a convertire i messaggi in oggetti java.

Abbiamo gia' visto nelle precedenti sezioni su xml qualcosa di simile, in particolare come realizzare dei client e servlet in grado di inviare e ricevere messaggi XML su HTTP. Allo stesso modo potremmo quindi far viaggiare messaggi SOAP su HTTP. Tuttavia per il trattamento di messaggi SOAP esiste una specifica standard in java, che ne ottimizza la gestione (SAAJ: SOAP with Attachments API for Java). Vediamo quindi come servirci di questa libreria per imbustare il nostro ordine in un messaggio SOAP.

4.3.2.1. Message Level Service

In precedenza abbiamo implementato un servizio in base alle operazioni che espone, ovvero un servizio che lavora a livello di operazioni. Se vogliamo implementare un servizio che lavori direttamente sul messaggio ricevuto possiamo implementarlo in questo modo:

@WebServiceProvider
@ServiceMode(value=Service.Mode.MESSAGE)‏
public class OrdiniService implements Provider<SOAPMessage>{
  public SOAPMessage invoke(SOAPMessage request) {
    SOAPMessage response = null;
    ...
    return response;
  }
}

Il servizio puo' quindi essere implementato agendo sull'oggetto SOAPMessage usando la API SAAJ ed un normale parser xml:

SOAPPart sp = request.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
SOAPBody sb = se.getBody();
SOAPHeader sh = se.getHeader()‏

org.w3c.dom.Document dom =
		sb.extractContentAsDocument();
NodeList node = dom.getElementsByTagName("ordine");
...

4.3.2.2. SAAJ Client

Anche sul versante client puo' essere usato SOAP, come segue:

  • Si instanzia una javax.xml.soap.MessageFactory

  • Con la MessageFactory si costruisce un javax.xml.soap.SOAPMessage

  • Si popola il SOAPMessage coi nodi necessari

  • Si invia la busta SOAP usando un SOAPConnector

Vediamo nel seguito il codice da utilizzare.

//Istanziamo una MessageFactory
MessageFactory mf = MessageFactory.newInstance();

//Costruiamo il SOAPMessage vuoto
SOAPMessage msg = mf.createMessage();

//Popoliamo il body del SOAPMessage con i nodi necessari
SOAPElement pagamento = msg.getSOAPBody().addChildElement("pagamento", "pay", "http://www.bank.org/ns");

pagamento.addChildElement("da","pay").setNodeValue("cliente");
pagamento.addChildElement("a","pay").setNodeValue("shop");
pagamento.addChildElement("importo","pay").setNodeValue("100");

//Scriviamo il SOAPMessage nel messaggio HTTP e riceviamo la risposta

SOAPConnectionFactory scFactory = SOAPConnectionFactory.newInstance();
SOAPConnection con = scFactory.createConnection(); 
java.net.URL endpoint = new URL("http://rivenditore.com/ordina");
SOAPMessage response = con.call(message, endpoint); 
...

                 

Footer BGFooter BG
Tito Flagella - © 2007-2015