Introduzione ai Web Services
-
Upload
marco-livraghi -
Category
Technology
-
view
104 -
download
2
Transcript of Introduzione ai Web Services
Spin off dell’Università degli Studi di Bari
Solutions Innovative
Do#. Marco Livraghi Product Manager User eXperience Designer So:ware Engineer
INTRODUZIONE AI WEB SERVICES
Spin off dell’Università degli Studi di Bari
L’idea base
Spin off dell’Università degli Studi di Bari
Sommario
l Cosa sono i Web service
l Le specifiche su cui si basano: – SOAP – WSDL – UDDI
l Un codice di esempio
Spin off dell’Università degli Studi di Bari
L’idea del webservice
Spin off dell’Università degli Studi di Bari
I webservice come interfaccia
Spin off dell’Università degli Studi di Bari
Web Service Message Exchange Patterns
Spin off dell’Università degli Studi di Bari
Web Service: definizione
Mediante web service è possibile supportare interazioni tra macchine mediante: 1. La descrizione di interfacce in formato
processabile dal calcolatore (linguaggio WSDL).
2. Lo scambio di messaggi (protocollo SOAP).
Spin off dell’Università degli Studi di Bari
Web Service: definizione • W3C Definition: [A Web service is a software system
designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine-processable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP messages]
• Un Web service è un componente software: – Accessibile mediante un protocollo denominato SOAP (Simple
Object Access Protocol), facilmente implementabile sopra HTTP – La cui interfaccia è descritta da un documento XML che segue il
formato WSDL (Web Service Description Language)
• I Web service si basano sulle specifiche XML, SOAP, WSDL, UDDI.
Spin off dell’Università degli Studi di Bari
Requisiti per la soluzione
• Un protocollo di trasporto che consenta la comunicazione mediante HTTP
• Interoperabilità mediante scambio di messaggi
• Formattazione dei messaggi tramite XML • Pubblicazione dei servizi mediante un registro
pubblico basato su XML à TOTALE INDIPENDENZA DALLE TECNOLOGIE DI SVILUPPO DEI SINGOLI SERVIZI E DALLE INFRASTRUTTURE DI RETE
Spin off dell’Università degli Studi di Bari
Web Service Stack L’architettura dei Web Services è definita su sei livelli (layers) di tecnologie e standard
Service Integration
Service Discovery
Service Publication
Service Description
XML - based Messaging
Transport
BPEL4WS IBM , Microsoft & BEA WCSI Sun BPML BPMI.org WSFL IBM XLANG Microsoft ebBPSS ebXML .org
UDDI UDDI.org ebXML ebXML .org
UDDI UDDI.org ebXML ebXML .org
WSDL W3C
XMLP W3C SOAP W3C XML W3C
HTTPR IBM HTTP W3C
Spin off dell’Università degli Studi di Bari
Web services: i livelli
• Trasporto: copre gli aspetti relativi allo scambio di messaggi tra applicazione e web service. (HTTP e non solo…)
• Messaggi: standardizza le regole di formattazione dell’informazione scambiata tra web service e applicazione (SOAP)
• Descrizione dei servizi: stabilisce un formato XML per la rappresentazione delle interfacce offerte da un web service. (UDDI: Uniform Description, Discovery and Integration)
Spin off dell’Università degli Studi di Bari
Web services: i livelli
• Ricerca: la individuazione del servizio può avvenire prima di lanciare il servizio (staticamente). L’alternativa prevede che ci sia un servizio che supporti una fase i negoziazione per capire quale servizio è il più adatto (dinamicamente).
• Integrazione: si occupa di gestire gli aspetti legati all’uso contemporaneo di più web service
Spin off dell’Università degli Studi di Bari
Example – A simple Web Service • A buyer (which might be a simple client) is ordering
goods from a seller service. • The buyer finds the seller service by searching the UDDI
directory. • The seller service is a Web Service whose interface is
defined using Web Services Description Language (WSDL).
• The buyer is invoking the order method on the seller service using Simple Object Access Protocol (SOAP) and the WSDL definition for the seller service.
• The buyer knows what to expect in the SOAP reply message because this is defined in the WSDL definition for the seller service.
Spin off dell’Università degli Studi di Bari
The Web Service Model
• The Web Services architecture is based upon the interactions between three roles: – Service provider – Service registry – Service requestor
• The interactions involve the: – Publish operations – Find operation – Bind operations.
Spin off dell’Università degli Studi di Bari
The Web Service Model (cont) The Web Services model follows the
publish, find, and bind paradigm.
1. publish 2. find
3. bind/invoke
Web Service Registry
Web Service Provider
Web Service Client
Spin off dell’Università degli Studi di Bari
XML • XML stands for EXtensible Markup
Language. • XML is a markup language much like
HTML. • XML was designed to describe data. • XML tags are not predefined. You must
define your own tags. • The prefect choice for enabling cross-
platform data communication in Web Services.
Spin off dell’Università degli Studi di Bari
XML vs HTML
An HTML example: <html> <body> <h2>John Doe</h2> <p>2 Backroads Lane<br> New York<br> 045935435<br> [email protected]<br> </p> </body> </html>
Spin off dell’Università degli Studi di Bari
XML vs HTML • This will be displayed as:
• HTML specifies how the document is to be
displayed, and not what information is contained in the document.
• Hard for machine to extract the embedded information. Relatively easy for human.
John Doe 2 Backroads Lane New York 045935435 [email protected]
Spin off dell’Università degli Studi di Bari
XML vs HTML • Now look at the following:
• In this case: – The information contained is being marked, but not for
displaying. – Readable by both human and machines.
<?xml version=1.0?> <contact> <name>John Doe</name> <address>2 Backroads Lane</address> <country>New York</country> <phone>045935435</phone> <email>[email protected]</email> </contact>
Spin off dell’Università degli Studi di Bari
SOAP: Simple Object Access Protocol (v. 1.2)
• Protocollo di scambio di informazioni in formato XML tra attori qualsiasi
• Definisce un formato generico di messaggio XML • E’ un paradigma di scambio stateless e one-way • Pattern di interazione più complessi (es. Richiesta/risposta,…) devono essere definiti a livello applicativo
• Specifica le azioni che gli attori della conversazione (i SOAP processors) devono svolgere al momento della ricezione dei messaggi
• Non descrive – La semantica dei dati trasportati, – L’implementazione della comunicazione – La qualità del trasporto (affidabilità, routing)
Spin off dell’Università degli Studi di Bari
SOAP: scenario e componenti
• SOAP prevede un processing model distribuito: – un SOAP message – viene inviato da un SOAP sender – è diretto ad un SOAP receiver finale – attraverso zero o più SOAP intermediaries
• Il SOAP processing model specifica in che modo un SOAP receiver processa un SOAP message. – Si applica ad un singolo messaggio,
isolato da tutti gli altri
Spin off dell’Università degli Studi di Bari
SOAP: scenario e componenti
• Nel processare i SOAP message, un nodo SOAP agisce in uno o più SOAP roles
• Ciascun role è identificato da un URI chiamato SOAP role name
• I ruoli assunti da un nodo non possono variare nell'atto di processare un messaggio
Spin off dell’Università degli Studi di Bari
Formato dei messaggi SOAP • Envelope: il contenitore
delle diverse parti delmessaggio
• Body (obbligatorio): parte centrale del messaggio
• Header (opzionale): informazioni addizionali al messaggio, divise in blocchi, per i diversi attori coinvolti
• I contenuti di ogni parte NON sono specificati in SOAP
SOAP Envelope
SOAP Header (opzionale)
SOAP Body (obbligatorio)
Header Block 1 …………
Header Block N
Spin off dell’Università degli Studi di Bari
Esempio di messaggio SOAP <?xml version=’1.0’ ?> <env:Envelope xmlns:env=”http://www.w3.org/2001/12/soap-envelope”> <env:Header> <m:reservation xmlns:m=”http://webml.org/reservation”> <m:reference>abl:0932 </reference> <m:dateAndTime>2001-11-29 13:35:00</m:dateAndTime> </m:reservation> <n:passenger xmlns:n=”http://webml.org/employees”> <n:name>John Smith</n:name> </n:passenger> </env:Header>
<env:Body> <p:itinerary xmlns:p=”http://webml.org/reservation/travel”> <p:airportChoices> JFK LGA EWR </p:airportChoices> </p:itinerary> </env:Body> </env:Envelope>
Spin off dell’Università degli Studi di Bari
L’uso dei namespace nei messaggi SOAP
• Poichè in XML i nomi degli elementi non sono fissati a priori è spesso possibile che si verifichino conflitti quando due documenti usano lo stesso nome per descrivere due diversi tipi di elementi
XHTML: <table> <tr> <td>Apples</td> <td>Bananas</td> </tr> </table>
Mobilio: <table> <name>African Coffee Table </name> <width>80</width> <length>120</length> </table>
Spin off dell’Università degli Studi di Bari
• I namespace sono dei semplici prefissi usati per evitare conflitti tra elementi con lo stesso nome
• La sintassi: xmlns:namespace-prefix="namespace" <f:table xmlns:f="http://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length>
</f:table>
• L'attributo xmlns associa al prefisso "f" un qualified name (un URI) • Nota: viene usato un URI semplicemente per dare al namespace
un identificativo unico, non viene usato dal parser per recuperare informazioni
L’uso dei namespace nei messaggi SOAP
Spin off dell’Università degli Studi di Bari
I namespace usati nello standard (SOAP 1.2)
• xmlns:env=http://www.w3.org/2003/05/soap-envelope
• xmlns:rpc=http://www.w3.org/2003/05/soap-rpc
• xmlns:SOAP-ENC = http://schemas.xmlsoap.org/soap/encoding/
• xmlns:xsd=http://www.w3.org/1999/XMLSchema
• xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
Spin off dell’Università degli Studi di Bari
SOAP processing model (1) • Descrive le azioni che un SOAP processor deve svolgere alla
ricezione di un messaggio SOAP • Il processor deve saper riconoscere le parti di messaggio
specifiche di SOAP (“env” namespace: envelope, header, body, header blocks)
• Un header block può contenere un attributo role (actor in SOAP 1.1) che specifica il ruolo del destinatario di quel blocco. Ruoli standard sono: – next: ("http://www.w3.org/2003/05/soap-envelope/role/next"): il ruolo che
deve essere assunto da tutti gli intermediari e dal nodo ficevente finale. . – none: ("http://www.w3.org/2003/05/soap-envelope/role/none"): denota
che un header block NON è destinato ad alcun nodo SOAP – ultimateReceiver: ("http://www.w3.org/2003/05/soap-envelope/role/
ultimateReceiver“): il ruolo che deve essere ricoperto dall’utimo ricevente
Spin off dell’Università degli Studi di Bari
SOAP processing model(2) • Un Header block può contenere l’attributo mustUnderstand:
dice se altre azioni devono essere svolte oltre al corretto riconoscimento del blocco da parte dell’attore
• mustUnderstand = “true”: il SOAP processor destinatario deve processare il blocco, comprendendone la semantica svolgendo eventualmente azioni specifiche (es., rimuovere l’header, modificare l’header, …); se non è in grado di farlo deve generare un errore(fault).
• Scopo: esser certi che un SOAP processor non ignori mai dei blocchi significativi
• L’elemento Body non ha attributo mustUnderstand
• Generalmente un SOAP processor genera SOAP fault o nuovi SOAP messages che verranno consumati da altri processors
Spin off dell’Università degli Studi di Bari
Stili di scambio messaggi • Document style: si adotta quando i servizi richiedono di
scabiarsi veri e propri documenti/dati XML – Il Body contiene il contenuto informativo del messaggio formattato in XML – Il documento scambiato può avere struttura e contenuti qualunque, non
definiti a priori
• RPC style: si adotta quando chiamata si vuole invocare una procedura remota – Utilizza una struttura del corpo del messaggio convenzionale che
rappresenta le informazioni necessarie per una RPC: nome della procedura o metodo, segnatura (opzionale), parametri
– La risposta della RPC (cioè il valore di ritorno della chiamata) è restituita nel Body di un altro messaggio SOAP, secondo il meccanismo richiesta-risposta (p.e: la chiamata è inviata mediante request HTTP e la risposta fornita come respons HTTP)
Spin off dell’Università degli Studi di Bari
RPC vs Document • RPC:
– Realizza un’invocazione di procedura – Basata sulla segnatura della procedura – Sincrona – Effettua il marshalling/unmarshalling dei parametri da/
verso XML
• Document – Sia sincrona che asincrona – Basata sui contenuti del documento – Usata quando si devono scambiare dati semistrutturati e
di una certa dimensione
Spin off dell’Università degli Studi di Bari
Esempio RPC SOAP • Supponiamo di dover chiamare una procedura del tipo:
• double GetStockQuote ( [in] string sSymbol );
• La chiamata si rappresenta in SOAP con un messaggio dalla struttura convenzionale:
<q:GetStockQuote xmlns:q="http://www.wroxstox.com/"> <q:sSymbol xsi:type="xsd:string">OU812</q:sSymbol> </q:GetStockQuote>
• La convenzione di chiamata stabilisce una corrispondenza tra nome della procedura e dei parametri in ingresso e nomi degli elementi da usarsi nel messaggio SOAP
Spin off dell’Università degli Studi di Bari
Risposta a chiamata RPC SOAP
• Esempio: • string ReverseString ( [in] string s );
• Rappresentazione convenzionale della risposta:
<x:ReverseStringResponse xmlns:x="http://www.wrox.com/">
<x:ret xsi:type="xsd:string">THOR</x:ret> </x:ReverseString>
• NB: si possono rappresentare in modo simile anche risposte a chiamate di procedura con parametri OUT e INOUT
Spin off dell’Università degli Studi di Bari
Gestione errori: SOAP fault • SOAP fornisce un modello per gestire situazioni di
errore nella elaborazione di un messaggio
• L’elemento Body ha un sottoelemento particolare (Fault) in cui specificare le informazioni sull’errore verificatosi
• L’elemento Fault, nel Body, contiene: " Faultcode: sub-elemento standard " Faultstring: sub-elemento standard " Details (opzionale): informazioni applicative specifiche " Faultactor (opzionale): identifica il SOAP processor che
ha generato l’errore
Spin off dell’Università degli Studi di Bari
SOAP Binding • I messaggi SOAP possono essere scambiati usando diversi
protocolli. La specifica di come i messaggi sono passati da un nodo ad un altro usando un protocollo prende il nome di SOAP binding
• I due binding più diffusi di SOAP usano HTTP o SMTP, ma si possono prevedere anche altri vettori (socket, messaggi MQseries, ecc..)
• Uso tipico di HTTP • RPC: POST request con il messaggio contenente i dati di
invocazione, POST response contenente il valore di ritorno • Document: POST request con il documento inviato ed
endpoint URL a cui inviare il documento di risposta
Spin off dell’Università degli Studi di Bari
SOAP Encoding • L’invio di un messaggio può richiedere la codifica dei
parametri attesi dal ricevente • Sorge il problema di come rappresentare in XML valori di
tipi complessi (p.e.: array, record, ecc..) • Lo stile di codifica viene dichiarato usando l’attributo
encodingStyle, che può qualificare qualunque elemento di un messaggio (ma che solitamente si mette nella SOAP envelope)
• SOAP fornisce uno stile di encoding (http://schemas.xmlsoap.org/soap/encoding/) che usa XML schema per la rappresentazione dei valori serializzati
• SOAP encoding tratta tipi di dati semplici, enumerativi, dati binari, tipi composti (structs, array), riferimenti, ecc..
Spin off dell’Università degli Studi di Bari
SOAP + HTTP
• E’ il binding più usato • Sfrutta il metodo POST e le entity HTTP come vettori
del messaggio SOAP
• Sfrutta HTTP URL per identificare il processore destinatario del messaggio
• La request utilizza uno header speciale (SOAPAction) che indica informazione opzionale sul motivo della request HTTP utilizzabile dai proxy oppure dal ricevente
• La response usa gli error code HTTP, abbinati al fault header di SOAP
Spin off dell’Università degli Studi di Bari
Esempio SOAP+HTTP request POST /endpoint.asp HTTP/1.1 Content-Type: text/xml Content-Length: ### SOAPAction: "urn:wroxheroes" <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/
envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap /encoding/"> <soap:Header> <h:from xmlns:h="http://www.wrox.com/Header"> [email protected] </h:from> </soap:Header> <soap:Body> <w:GetSecretIdentity xmlns:w="http://www.wrox.com/heroes/"> <codename>XSLT-Man</codename> </w:GetSecretIdentity> </soap:Body> </soap:Envelope>
Spin off dell’Università degli Studi di Bari
Esempio: SOAP+HTTP response
HTTP/1.1 200 OK Content-Type: text/xml Content-Length: ### <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/
envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap /encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <soap:Body> <m:GetSecretIdentityResponse xmlns:m="http://www.wrox.com/
heroes/"> <return xsi:type="xsd:string">Michael Kay</return> </m:GetSecretIdentityResponse> </soap:Body> </soap:Envelope>
Spin off dell’Università degli Studi di Bari
Esempio: SOAP+HTTP response con errore HTTP/1.1 500 Internal Server Error Content-Type: text/xml Content-Length: ### <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap /encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <soap:Body> <soap:Fault> <faultcode>soap:VersionMismatch</faultcode> <faultstring>The SOAP namespace is incorrect.</faultstring> <faultactor>http://www.wrox.com/endpoint.asp</faultactor> <detail> <w:errorinfo xmlns:w="http://www.wrox.com/"> <desc>The SOAP namespace was blank.</desc> </w:errorinfo> </detail> </soap:Fault> </soap:Body> </soap:Envelope>
Spin off dell’Università degli Studi di Bari
Descrizione dei servizi
• Limiti di SOAP: – Nonostante il nome, SOAP non è veramante object-
oriented, ma solo message-oriented – Non si può descrivere un servizio complesso, formato
da diversi metodi – Non si può descrivere la corrispondenza tra messaggi
di richiesta e messaggi di risposta – Non si può descrivere il tipo di dati che costituiscono
la richiesta e la risposta
Spin off dell’Università degli Studi di Bari
Web Service Description Language
• DEFINIZIONE: WSDL è un linguaggio basato su XML per definire e descrivere Web services
• WSDL descrive un servizio fornendo le informazioni necessarie per sviluppare client che intendano utilizzarlo seguendo la sintassi XML
• Contenuti: Un documento WSDL specifica la locazione (URL) del servizio e le operazioni offerte, mediante: – Una descrizione astratta di una classe di servizi – Un insieme di descrizioni di servizi concreti, conformi alla
descrizione astratta
Spin off dell’Università degli Studi di Bari
Descrizione dei tipi
• La parte astratta di un descrittore WSDL specifica: – Un insieme (opzionale) di TIPI (types): nuovi tipi XML
schema che potranno essere usati nella specifica – Un insieme di MESSAGGI (messages): descrizioni
astratte (tipi e nomi) dei dati scambiati con il Service (eventualmente usando i types sopra definiti)
– Un insieme di OPERAZIONI (operations): descrizioni astratte delle azioni supportate da un Service
– Uno o più PORT TYPE: insiemi di operazioni correlate dal punto di vista applicativo
Spin off dell’Università degli Studi di Bari
Descrizione dell’implementazione
• La parte concreta di un descrittore WSDL specifica: – Binding: il particolare protocollo di comunicazione per un
certo port type. E’ possibile specificare diversi binding per un lo stesso port type (es. su HTTP, SMTP ecc.)
– Port: modulo concreto costituito da: n un port type [interfaccia e specifica del servizio] n un binding [come funziona il servizio] n un indirizzo di rete (URL) [dove trovare il servizio]
– Service: fornitore di servizi concreto formato da un insieme di port
Spin off dell’Università degli Studi di Bari
Struttura di un documento WSDL <definitions>
<types> i tipi di dati che verranno trasmessi
</types> <message>
i messaggi scambiati </message> <portType>
le operazioni (funzioni) supportate </portType> <binding>
come si scambiano i messaggi (dettagli SOAP) </binding> <service>
dove trovare il servizio </service>
</definitions>
Spin off dell’Università degli Studi di Bari
Struttura di un documento WSDL <definitions>
<types> i tipi di dati che verranno trasmessi
</types> <message>
i messaggi scambiati </message> <portType>
le operazioni (funzioni) supportate </portType> <binding>
come si scambiano i messaggi (dettagli SOAP) </binding> <service>
dove trovare il servizio </service>
</definitions>
Spin off dell’Università degli Studi di Bari
Tipi di operazioni WSDL Un’operazione (operation) può essere:
• one-way:il service riceve un messaggio (input message)
• request-response: il service riceve una richiesta(input message) e restituisce la risposta relativa(output message)
• solicit-response: il service invia un messaggio (output message) e riceve una risposta (input message)
• notification: il servizio invia un messaggio (output message)
Spin off dell’Università degli Studi di Bari
Asincronismo delle operazioni • L’operation è l’unità di interazione elementare con un Web
service, ed è eseguita attraverso lo scambio di messaggi.
• Convenzionalmente: – input messages: inviati dall’utilizzatore al Service – output messages: messaggi inviati dal Service.
• L’interazione con i Web Services può essere asincrona. Scambi asincroni possono verificarsi all’interno di una operazione a due messaggi, oppure tra due operazioni a messaggio singolo
• Nel caso di operazioni binarie asincrone su protocolli sincroni (es: HTTP) l’implementazione deve occuparsi della correlazione dei messaggi: p.e. usando SOAP header di tipo “reply-to”
Spin off dell’Università degli Studi di Bari
Esempio (parte 1) <message name=”getTranslationRequest”> <part name=”word” type=”xs:string”/> </message> <message name=”getTranslationResponse”> <part name=”value” type=”xs:string”/> </message> <portType name=”dictionaryService”>
<operation name=”getTranslation”> <input message=”getTranslationRequest”/> <output message=”getTranslationResponse”/> </operation> … altre operations...
</portType>
Request-response operation
Spin off dell’Università degli Studi di Bari
Esempio (parte 2) – SOAP binding
<binding type=”dictionaryService” name=”bind1”> <soap:binding style=”document” transport=”http://schemas.xmlsoap.org/soap/http” /> <operation> <soap:operation soapAction=”http://webml.org/getTransl”/> <input> <soap:body use=”literal”/> </input> <output> <soap:body use="encoded" namespace="urn:enc-name"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding>
Eventuale Tipo di encoding
rpc o document
riferimento al portType
SOAP su HTTP
Spin off dell’Università degli Studi di Bari
Esempio (parte 3) - endpoint
<service name="dictService"> <port name="dictionaryService” binding="bind1"> <soap:address location="http://www.dict.com/serv"/> </port> </service>
PortType Binding
End Point
Spin off dell’Università degli Studi di Bari
WSDL: un esempio completo (1/2) <?xml version="1.0" ?> <definitions name="BabelFishService" xmlns:tns="http://www.xmethods.net/sd/
BabelFishService.wsdl" targetNamespace="http://www.xmethods.net/sd/BabelFishService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/">
- <message name="BabelFishRequest"> <part name="translationmode" type="xsd:string" /> <part name="sourcedata" type="xsd:string" /> </message> - <message name="BabelFishResponse"> <part name="return" type="xsd:string" /> </message> - <portType name="BabelFishPortType"> - <operation name="BabelFish"> <input message="tns:BabelFishRequest" /> <output message="tns:BabelFishResponse" /> </operation> </portType> ...
Spin off dell’Università degli Studi di Bari
WSDL: un esempio completo (2/2) ... - <binding name="BabelFishBinding" type="tns:BabelFishPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> - <operation name="BabelFish"> <soap:operation soapAction="urn:xmethodsBabelFish#BabelFish" /> - <input> <soap:body use="encoded" namespace="urn:xmethodsBabelFish" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> </input> - <output> <soap:body use="encoded" namespace="urn:xmethodsBabelFish" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> </output> </operation> </binding> - <service name="BabelFishService"> <documentation>Translates text of up to 5k in length, between a variety of
languages.</documentation> - <port name="BabelFishPort" binding="tns:BabelFishBinding"> <soap:address location="http://services.xmethods.net:80/perl/soaplite.cgi" /> </port> </service> </definitions> (www.xmethods.com)
Spin off dell’Università degli Studi di Bari
Uniform Description, Discovery and Integration
• Scopo: implementare un catalogo (stile “pagine gialle”) in cui è possibile registrare servizi, per permettere ai potenziali utilizzatori di localizzarli
• UDDI è una specifica ad alto livello di un sistema distribuito (ed eventualmente replicato) di catalogazione di servizi descritti in WSDL
• UDDI non è un servizio di ricerca completo e strutturato
• Un registro UDDI è esso stesso accessibile mediante Web Service
Spin off dell’Università degli Studi di Bari
Le informazioni in UDDI Le informazioni memorizzate da UDDI sono: • businessEntity: gli attori che pubblicano i servizi. Possono
anche contenere informazioni per classificare tali attori (lozalizzazione, tipologia di attore e di servizi forniti, …)
• businessService: contenitore di una famiglia di servizi correlati • bindingTemplate: descrizione tecnica del servizio: ciò che è
necessario per connettersi e comunicare con il servizio (url del servizio e uno o più riferimenti a service models)
• Il service model è una descrizione astratta del servizio, che dice cosa fa, qual è la sintassi dei messaggi che accetta, ecc. Non è descritto da UDDI, ma da altri standard
• Una businessEntity può pubblicare molti businessServices, ciascuno dei quali può avere più bindingTemplate
Spin off dell’Università degli Studi di Bari
Operazioni in UDDI UDDI consente di: • Registrare (una businessEntity, contenente
businessServices, ecc.); una chiave univoca viene assegnata e la sottomissione è replicata su tutti i registri UDDI.
• Cercare, cioè effettuare interrogazioni sulle descrizioni UDDI di servizi, secondo i criteri di ricerca specificati. Il risultato è l’insieme delle chiavi dei servizi corrispondenti
• Recuperare i dati di un preciso servizio/entità/binding di cui è nota la chiave.
Spin off dell’Università degli Studi di Bari
UDDI implementations
• Per garantire l’accesso ai registri UDDI da ogni piattaforma, le directory UDDI espongono un insieme di API sotto forma di Web services basati su SOAP.
• Attualmente i servizi UDDI sono forniti solo pochi providers: – IBM – Microsoft – Xmethods – SAP
Spin off dell’Università degli Studi di Bari
UDDI Registries + client
l http://uddi.ibm.com/ l http://uddi.microsoft.com/ l http://uddi.sap.com/ l http://www.ntt.com/uddi/ l Client: http://soapclient.com
Spin off dell’Università degli Studi di Bari
UDDI Query find_binding: Used to locate specific bindings within a registered businessService. Returns a bindingDetail message. find_business: Used to locate informa=on about one or more businesses. Returns a businessList message. find_relatedBusinesses: Used to locate informa=on about businessEn=ty registra=ons that are related to a specific business en=ty whose key is passed in the inquiry. The Related Businesses feature is used to manage registra=on of business units and subsequently relate them based on organiza=onal hierarchies or business partner rela=onships. Returns a relatedBusinessesList message. find_service: Used to locate specific services within a registered businessEn=ty. Returns a serviceList message. find_tModel: Used to locate one or more tModel (technical fingerprint of a par=cular soHware interface) informa=on structures. Returns a tModelList structure. get_bindingDetail: Used to get full bindingTemplate informa=on suitable for making one or more service requests. Returns a bindingDetail message. get_businessDetail: Used to get the full businessEn=ty informa=on for one or more businesses or organiza=ons. Returns a businessDetail message. get_businessDetailExt: Used to get extended businessEn=ty informa=on. Returns a businessDetailExt message. get_serviceDetail: Used to get full details for a given set of registered businessService data. Returns a serviceDetail message. get_tModelDetail: Used to get full details for a given set of registered tModel data. Returns a tModelDetail message.
Spin off dell’Università degli Studi di Bari
Esempio UDDI - request <Envelope>
<Body> <find_business generic="1.0" maxRows="100">
<findQualifiers/> <name>google</name>
</find_business> </Body>
</Envelope>
Spin off dell’Università degli Studi di Bari
Esempio UDDI - response <soap:Envelope>
<soap:Body> <businessList generic="1.0" operator="Microsoft Corporation" truncated="false">
<businessInfos> <businessInfo businessKey="824f69e0-6f23-11d7-
b2e8-000629dc0a53"> <name>GoogleWebService</name> <description xml:lang="en">service for Discovery base on Web
services</description> <serviceInfos/> </businessInfo>
</businessInfos> </businessList>
</soap:Body> </soap:Envelope>
Spin off dell’Università degli Studi di Bari
Riferimenti
• Standard (obbligatori): – SOAP www.w3.org/TR/soap – WSDL www.w3.org/TR/wsdl – UDDI www.uddi.org/specification.html
• SOAP: Henri Bequet “Professional Java SOAP” Cap. 2 http://www.perfectxml.com/SOAPIntro.asp#chap
• WSDL: Ethan Cerami “Web Service Essentials” Cap. 6 http://www.oreilly.com/catalog/webservess/chapter/ch06.html
• http://soapclient.com
Spin off dell’Università degli Studi di Bari
Altre fonti
l www.w3c.org l www.sun.com l http://otn.oracle.com/tech/webservices l http://www.onjava.com l http://uddi.org
Spin off dell’Università degli Studi di Bari
Solutions Innovative
Spin off dell’Università degli Studi di Bari
Solutions Innovative
1a Servlet
Spin off dell’Università degli Studi di Bari
Le form Html e le Servlet • Le form HTML permettono l’input dei dati
tramite le loro caselle di testo, ma non possono elaborare questa informazione per creare una risposta dinamica.
• Per elaborare l’informazione possiamo usare una SERVLET
• Questa è uno speciale programma java che può estrarre l’informazione da una request, ed inviare al cliente la risposta (response) desiderata
Spin off dell’Università degli Studi di Bari
Client - Server
Spin off dell’Università degli Studi di Bari
Che cosa fa il web server ?
Spin off dell’Università degli Studi di Bari
Che cosa fa il client ?
Spin off dell’Università degli Studi di Bari
Il client browser ottiene l’HTML e lo visualizza all’utente
Spin off dell’Università degli Studi di Bari
Il protocollo HTTP
Spin off dell’Università degli Studi di Bari
Html è parte della risposta http
Spin off dell’Università degli Studi di Bari
Che cosa c’è nella request ? GET
Spin off dell’Università degli Studi di Bari
Che cosa c’è nella Request: POST
Spin off dell’Università degli Studi di Bari
Anatomia di una request GET
Spin off dell’Università degli Studi di Bari
Anatomia di una richiesta POST
Spin off dell’Università degli Studi di Bari
Anatomia di una response HTTP
Spin off dell’Università degli Studi di Bari
Architettura Il package Java di base per le API Servlet è javax.servlet:
– contiene la definizione dell’interfaccia Servlet e – contiene classi utili alla comunicazione fra client e server
L’interfaccia Servlet
– contiene i prototipi di tutti i metodi necessari alla gestione del ciclo di vita di una servlet e alla esecuzione delle operazione implementate dalla servlet
– i metodi definiti in questa intefaccia devono essere supportati da tutte le servlet
Tutte le servlet sono classi che implementano l’intefaccia servlet, o in maniera diretta, o estendendo una classe che la implementa come ad esempio HttpServlet
Spin off dell’Università degli Studi di Bari
Architettura Il package javax.servlet.http fornisce classi che estendono le funzionalità di base di una servlet adottando le caratteristiche del protocollo http come
– gestione dei metodi HTTP (GET, POST) – gestione degli header HTTP
Per creare una servlet che utilizzi il protocollo http per ricevere e fornire dati si può implementare una classe che estenda la classe javax.servlet.http.HttpServlet
Spin off dell’Università degli Studi di Bari
Architettura
Quando una servlet accetta una richiesta da un client riceve due oggetti:
– ServletRequest, utilizzato per la comunicazioner dal client verso il server
– ServletResponse, utilizzato per gestire la comunicazioie dal server verso il client
Estensioni di queste classi consentono di disporre di metodi per manipolare informazioni e header specifici di determinati protocolli. In particolare le servlet che utilizzano il protocollo HTTP usano oggetti che sono istanza delle classi HttpServletRequest e HttpServletResponse
Spin off dell’Università degli Studi di Bari
Servlet concorrenti - Il web server per definizione utilizza una sola istanza di servlet
condividendola fra le varie richieste - N richieste da parte di client della stessa servlet portano alla creazione di
n threads differenti da parte del web server capaci di eseguire la servlet in maniera concorrente.
- In fase di programmazione si deve tenere conto dei meccanismi di accesso concorrente alle servlet a ai loro dati.
- L’operatore synchronized consente di sincronizzare blocchi di codice della servlet ( o anche tutto il metodo service) difendendoli da accessi concorrenti da parte di più threads.
- Per creare più istanze di una stessa servlet da associare alle richieste, la servlet deve implementare l’interfaccia SingleThreadModel. In questo modo il web server creerà più istanza della stessa servlet al momento del caricamento dell’oggetto e assegnerà ai threads solo istanza libere.
Spin off dell’Università degli Studi di Bari
L’oggetto HttpServerRequest • Rappresenta una richiesta http e mediante i
metodi di questa classe è possibile – accedere a parametri o meta informazioni relative
alla richiesta. Es: • getRequestURI() restituisce l’URI richiesto • getMethod() fornisce il metodo HTTP utilizzato per
inoltrare la richiesta • il metodo getParameter(String) consente di accedere
per nome ai parametri contenuti nella query string – creare gli stream di input e la possibilità quindi di
ricevere i dati della richiesta attraverso i metodi getInputStream e getReader
Spin off dell’Università degli Studi di Bari
L’oggetto HttpServerResponse • Fornisce alla servlet i metodi per rispondere al
client: – permette di fissare parametri relativi alla risposta
inviata (come lunghezza o tipo MIME) – fornisce metodi per manipolare gli header del
protocollo http – rende possibile il reindirizzamento – fornisce i metodi per creare gli stream di output e la
possibilità quindi di inviare i dati della risposta. • getOutputStream per l’invio di dati in forma binaria • getWriter per l’invio attraverso il canale System.out
– definisce una serie di constanti per inviare al browser il risultato della operazione richiesta
Spin off dell’Università degli Studi di Bari
Ciclo di vita delle servlet Il ciclo di vita di una servlet definisce:
– come una servlet viene caricata: caricamento e istanziazione sono eseguiti dal web server e avvengono al momento della prima richiesta da parte dei client
– come una servlet viene inizializzata: in questa fase la servlet carica dati persistenti , apre connessioni verso DB. Questa operazione avviene tramite la chiamata al metodo init(). Il metodo di default non esegue nessuna operazione
– come può ricevere e rispondere alle richieste dei client: il metodo eseguto all’arrivo di una nuova richiesta è il metodo service(), che riceve come parametri gli oggetti ServletRequest e ServletResponse per gestire le richieste
– come viene terminata ( tipicamente quando termina l’esecuzione del web server): ad esempio si specifica come rilasciare le risorse occupate. Questa operazione avviene tramite la chiamata al metodo destroy()
Spin off dell’Università degli Studi di Bari
Inizializzazione di una servlet • L’inizializzazione di una servlet avviene con la chiamata del metodo
init() al momento del suo caricamento • Un solo threads viene eseguito al momento della inizializzazione • Le richieste possono essere ricevute dalla servlet solo dopo il
completamento della fase di inizializzazione • Se la servlet non riesce a completare l’inizializzazione viene
generata una eccezione • Il metodo init() riceve come parametro un oggetto di tipo
ServletConfig che contiene la configurazione iniziale di una servlet. Per salvare la configurazione si puo’ richiamare il metodo super.init, altrimenti si deve implemetare questa operazione nel nuovo init.
Spin off dell’Università degli Studi di Bari
Inizializzazione di una servlet • I parametri di configurazione di una servlet sono definiti
all’interno della configurazione del web server che li comunica alla servlet nella forma chiave=valore.
• I metodi utilizzati dall’oggetto ServletConfig per accedere ai parametri sono: getInitParameterNames() e getInitParameter(String)
• Si puo accedere ai parametri di configurazione anche tramite il metodo getServletConfig() dell’interfaccia servlet all’interno del metodo service()
Es. public void init(ServletConfig config){ super.init(config); String initpar = config.getInitParameter(‘PARAMETER’); if(initpar== null){ throw new UnavailableException(this,”errore!”) }}
Spin off dell’Università degli Studi di Bari
Il metodo service() ■ Se il metodo service() non viene sovrascritto, la nostra classe
eredita il metodo definito all’interno della classe che andiamo ad estendere
■ Se estendiamo la classeHttpServlet, questo metodo ha la funzione di distribuire la gestione della richiesta fra altri metodi in base al tipo di richiesta ricevuta. Ad esempio in caso di richiesta GET o POST vengono richiamati in automatico rispettivamente i metodi doGet() e doPost()
• ⇒ Nel caso non si implementi una nuova versione del metodo service() sarà necessario implementare nella nostra classe un metodo scelto fra questi in base al tipo di richiesta da gestire.
Spin off dell’Università degli Studi di Bari
Interazione con client • Scrivere una servlet che estende la classa HttpServlet per
gestire il protocollo HTTP comporta l’implementazione dei metodi definiti per gestire l’interazione HTTP col client che si ritengono necessari.
• Es. – doGet, per gestire richiesta di tipo GET o HEAD – doPost, per gestire richiesta di tipo POST – doPut, per gestire richiesta di tipo PUT
• Di default queste richieste restituiscono il codice HTTP BAD_REQUEST (400)
• Tali metodi ricevono tutti 2 argomenti, gli oggetti HttpServletRequest e HttpServletResponse per la gestione dei dati ricevuti o inviati al client
Spin off dell’Università degli Studi di Bari
Interazione con client • Il modo in cui si accede ai dati del client può dipendere dal
metodo HTTP della richiesta: – Con tutti i metodi HTTP, il metodo getParameterValues
fornisce i valori in base al nome del parametro, il metodo getParameterNames fornisce i nomi dei parametri
– Col metodo GET si può utilizzare il motodo getQueryString che restituisce una stringa da parserizzare
– Con i metodi POST,PUT si può scegliere fra i metodi getReader per la lettura di dati di tipo testo o getInputStream per la creazione di uno stream per la lettura di dati binari
• Per inviare dati al client sono disponibili invece i metodi – getWriter, per inviare dei dati di tipo testo – getOutputStream per inviare dati binari
Spin off dell’Università degli Studi di Bari
Interazione con client • Procedura per l’invio di dati ( per esempio nella
creazione di una pagina html dinamica):
■ Prima di inviare dati tramite l’oggetto Writer o OutputStream, è necessario fissare gli header HTTP.
■ La classe HttpServletResponse fornisce dei metodi per accedere e fissare gli header della risposta, come il content-type, encoding, content lenght.
■ Una volta impostati gli header della risposta, si può inviare il body
Spin off dell’Università degli Studi di Bari
Un esempio: Salve Mondo! • Vogliamo creare una servlet la cui chiamata da
parte di un client restituisca una semplice pagina HTML con la scritta “Salve Mondo!”:
■ Creiamo un file SalveMondoServlet.java ■ Compiliamo il file con javac per ottenere il file
SalveMondoServlet.class ■ Rendiamo il file disponibile via web attraverso un
URL
Spin off dell’Università degli Studi di Bari
Un esempio: Salve Mondo! ■ Import dei package necessari alla servlet • Import java.io.*; • import java.servlet.*; • import java.servlet.http.*; ■ Dichiarazione della classe che sarà la nostra
servlet. Poiché creaimo una servlet HTTP estendiamo la classe javax.servlet.http.HttpServlet
• public class SalveMondoServlet extends HttpServlet ■ Volendo far gestire alla nostra servlet richieste di
tipo GET, ridefiniamo il metodo doGet() protected void doGet(HttpServletRequest req, HttpServletResponse res)
■ Impostiamo il tipo MIME della risposta da inviare al client.
• res.setContentType(“text/html”);
Spin off dell’Università degli Studi di Bari
Un esempio: Salve Mondo! ■ Creiamo un oggetto PrintWriter associato alla
risposta per la scrittura verso il client. • PrinterWriter out =res.getWriter(); ■ Utilizziamo l’oggetto PrintWriter per creare il testo
della pagina da inviare al client. • out.println(“<HTML><HEAD><TITLE>SalveMondo!</TITLE>”); • out.println(“</HEAD><BODY>SalveMondo!</BODY></HTML>”); ■ Chiudiamo l’oggetto PrintWriter ( il server chiude
gli stream di input/output automaticamente alla terminazione dell’esecuzione di una servlet).
• out.close();
• Questa chiamata informa il server che la risposta è terminata e la connessione può essere chiusa
Spin off dell’Università degli Studi di Bari
Un esempio: Salve Mondo! Import java.io.*;!import java.servlet.*;!import java.servlet.http.*;!!public class SalveMondoServlet extends Httpservlet{!
!protected void doGet(HttpServletRequest req, HttpServletResponse)!! !throws ServletException, IOException{!! !res.setContentType(“text/html”);!! !PrinterWriter out =res.getWriter();!! !out.println(“<HTML><HEAD><TITLE>SalveMondo!</TITLE>”);!! !out.println(“</HEAD><BODY>SalveMondo!</BODY></HTML>”);!! !out.close();!!}!
}!
Spin off dell’Università degli Studi di Bari
Uso delle sessioni ■ Una sessione è rappresentata attraverso la classe
HttpSession ■ La creazione di una sessione può essere fatta all’interno
dei metodi doGet o doPost tramite il metodo getSession dell’oggetto HttpServletRequest
• HttpSession session = req.getSession(true); ■ Con questa chiamata la servlet cerca di identificare il
client, e se non esiste già una sessione associata alla richiesta ne viene creata una nuova.
■ Una volta ottenuto l’oggetto session, questo può essere utilizzato tramite i suoi metodi per memorizzare qualsiasi tipo di informazione.
■ Un sessione rimane valida finchè non viene invalidata col metodo invalidate(), oppure scade il suo timeout.
Spin off dell’Università degli Studi di Bari
Uso delle sessioni ■ La creazione di una sessione comporta in pratica la
predisposizione di un’area di memoria per la gestione delle informazioni e la creazione “trasparente” di un cookie con un numero di sessione.
■ Se il browser non supporta il cookie, il numero di sessione viene registrato nelle query string al momento della creazione del codice della pagina.
• http://localhost/servlet/myServlet?sessionID=9824765234931133
■ I metodi dell’oggetto HttpSession permettono di avere informazioni sulla sessione (id della sessione, tempo trascorso, tempo di inattività) o di memorizzare dati di sessione nella forma di coppia nome=valore.
• putValue(String name,Object value) • void removeValue(String name)
Spin off dell’Università degli Studi di Bari
Esempio di uso delle Sessioni public void service(HttpServletRequest req, HttpServletResponse)!
! !throws ServletException, IOException{!!res.setContentType(“text/html”);!!PrinterWriter out = res.getWriter();!!out.println(“…..”); //stampo i tag iniziali!!HttpSession sessione = req.getSession(true);!!if(session.isNew()){!! !out.println(“<br>Tempo di creazione:” +
sessione.getCreationTime());!! !sessione.putValue(“accessi”,new Integer(1));!!}else{!! !int
accessi=((Integer)session.getValue(“accessi”)).intValue();!! !accessi++; sessione.setAttribute("accessi", accessi);!! ! out.println(“<br>Numero accessi:”+accessi);}!!out.println(“<br>…”);!//stampo i tag finali!!out.close(); }!
Spin off dell’Università degli Studi di Bari
Solutions Innovative
1o webservices
Spin off dell’Università degli Studi di Bari
Tendenza: REST + payload JSON
Vantaggi: • sfrutta appieno il protocollo HTTP
• messaggi poco verbosi, meno
occupazione di banda
• ogni risorsa/servizio è referenziale in modo univoco tramite un URI
Spin off dell’Università degli Studi di Bari
Servizio SOAP con TOMCAT
Vantaggi: • tempi di realizzazione ridotti grazie al
generatore automatico di codice. • conversione agevole di app stand-alone
scritte in java in webservices • standard di fatto
Spin off dell’Università degli Studi di Bari
KISS: Keep It Simple, Stupid
Approccio buttom-up: implementiamo la classe java che “fa quelle cose” che vogliamo “trasformare” in un servizio:
File-‐>New-‐>Dynamic Web Project
Spin off dell’Università degli Studi di Bari
KISS: Keep It Simple, Stupid Con Input e Output definiti come:
NB: Secondo la specifica Java Bean, oltre ai geTer & seTer devo avere almeno un costruTore senza argomen=.
Spin off dell’Università degli Studi di Bari
Eclipse: il Producer Click destro sulla classe del nostro servizio, poi New-‐>Other… selezionare “Web Service” come in figura:
Spin off dell’Università degli Studi di Bari
Spin off dell’Università degli Studi di Bari
Il servizio viene generato e automa=camente deplorato su Tomcat. Al termine si apre una pagina di test del servizio. NB: Prima di proseguire selezionare anche “Monitor the Web Service” in basso in modo da monitorare i messaggi SOAP da dentro Eclipse.
Eclipse: il Producer
Spin off dell’Università degli Studi di Bari
Successivamente selezioniamo il nome del file WSDL che verrà creato e i metodi della classe che vogliamo esporre come servizio.
Spin off dell’Università degli Studi di Bari
Avviare Tomcat se non è già avviato.
Successivamente lanciare l’applicazione di test fornita da Eclipse:
Spin off dell’Università degli Studi di Bari
Al termine si aprirà il browser mostrando una pagina di questo =po:
Selezionando per esempio il metodo echo e inserendo una stringa, verrà visualizzato immediatamente il risultato res=tuito dal server.
Spin off dell’Università degli Studi di Bari
Le cartelle del progeTo…
DescriTore del servizio
Tornando ad Eclipse, possiamo verificare i messaggi scambia= dal tab “TCP/IP Monitor”:
Spin off dell’Università degli Studi di Bari
Guardando il web.xml si scopre che Eclipse ha aggiunto due nuova servlet: AxisServlet e AdminServlet !Queste due servlet ricevono le chiamate e le traducono per il nostro servizio in Java. Axis non è altro che una implementazione open source del protocollo SOAP per Java: ogni volta che avete a che fare con Axis quindi potete scoprire tutti i servizi deplorati sul server semplicemente richiamando un URI di questo tipo: http://localhost:8080/WebServiceProducerTest/services!!
che mostrerà gli URI dei WSDL, come quello appena creato: http://localhost:8080/WebServiceProducerTest/services/MyService?wsdl!!
Eclipse: il Producer
Spin off dell’Università degli Studi di Bari
Creiamo un nuovo progetto web: scegliamo target runtime, nome ecc… Al termine, click destro sulla cartella src, poi New à Other… e selezionare Web Service Client:!
Eclipse: il Consumer
Spin off dell’Università degli Studi di Bari
Inseriamo l’URL del WSDL del producer del servizio che vogliamo consumare (quello appena creato):!
Eclipse: il Consumer
Spin off dell’Università degli Studi di Bari
à Il WSDL si ottiene sempre aggiungendo il query param WSDL (non case sensitive) all’URL del servizio. Esempio: http://localhost:8080/WebServiceProducerTest/services/MyService?wsdl! !
Eclipse: il Consumer
Spin off dell’Università degli Studi di Bari
Selezioniamo il livello di deploy: scegliamo tra “Test service” o “Run service” e decidiamo di monitorare il servizio (“Monitor the Web Service”)!
Eclipse: il Consumer
Spin off dell’Università degli Studi di Bari
Se scegliamo di testare il servizio, nella schermata successiva verrà chiesto quali metodi testare: Eclipse creerà una pagina JSP per lo scopo. !
Eclipse: il Consumer
Spin off dell’Università degli Studi di Bari
Nel progetto sono apparse una serie di classi che ricordano il nome del servizio che abbiamo creato sul provider e dei parametri passati in input e output!
Codice generato automaticamente
Spin off dell’Università degli Studi di Bari
L’idea è quella di usare le classi generate come se il servizio fosse locale, trasparente allo sviluppatore: le classi create infatti fanno da proxy e nascondono tutta l’interazione col server che sta dietro le quinte. Come posso invocare il servizio remoto sul client in locale? !
Codice generato automaticamente classi Input e Output!
Spin off dell’Università degli Studi di Bari
Spin off dell’Università degli Studi di Bari
Solutions Innovative
Spin off dell’Università degli Studi di Bari
www.laresrl.com [email protected]