Corso di Laurea in Informatica Reti e Sicurezza Informatica Esercitazione 2 Prof. Mario Cannataro Ing. Giuseppe Pirrò I Web Service - Definizione (W3C) “A Web Service is a software system identified by a URI, whose public interfaces and bindings are defined and described using XML. Its definition can be discovered by other software systems. These systems may then interact with the Web Service in a manner prescribed by its definition, using XML-based messages conveyed by Internet protocols” I Web Service - Scenario di utilizzo Interoperabilità Business-to-customer (B2C) Business-to-business (B2B) Applicazioni Inter-aziendali Service Oriented Computing La Service Oriented Architecture Una SOA è essenzialmente una collezione di servizi che comunicano gli uni con gli altri. La comunicazione può riguardare il semplice scambio di dati o anche attività di coordinamento di attività che coinvolgono più servizi. Affinché questa comunicazione possa avvenire è necessario un “mezzo” di comunicazione. La SOA Descrizione di un Web Service Web Services Description Language descrive: 1. I servizi offerti da un Web Service I dati di input I dati di output Le modalità di invocazione del servizio 2. 3. 4. Descrizione di un Web Service 1. 2. E composta da due parti: Abstract view: descrizione delle operazioni permesse dal servizio, raggruppate come portType. Concrete view: Informazioni sull’implementazione delle operation. I Web Service - Requisiti Tecnologici Apache Tomcat (o qualsiasi altro server web) - Rende “sempre” disponibile il servizio Librerie per lo sviluppo di Web Service - Apache AXIS (Java) - gSOAP (C++) Le librerie AXIS AXIS è una Web Application Implementa gli standard per i Web Service Fornisce tool e librerie per lo sviluppo dei Web Service Le librerie AXIS - Installazione Scompattare le librerie scaricate Posizionare la directory axis_*/webapps nella sottodirectory webapps di Tomcat Il server Web al riavvio identificherà automaticamente il nuovo modulo aggiunto Le librerie AXIS - Verifica Installazione Puntare il browser all’URL: http://localhost:8080/axis Le librerie AXIS - Validazione Verificare che vengano caricate correttamente tutte le librerie cliccando sul link Validation presente nella home page di Axis. Verrà mostrata una pagina simile a quella seguente, nella quale non dovranno esserci messaggi di errori o di warning Le librerie AXIS – Verifica WSDL Cliccare su una delle voci WSDL dei servizi già disponibili per verificare la generazione del WSDL relativo al servizio Le librerie AXIS - Lista servizi attivati Per conoscere la lista dei servizi attivi basta cliccare sul link list nella home page di AXIS. REALIZZAZIONE DI WEB SERVICES Scrittura di web Services Un Web Service si realizza ( ad esempio in Java) attraverso la scrittura di una classe che implementi gli obbiettivi del servizio. Una volta scritta la classe si procede alla messa in opera del servizio. - Deploy del servizio Metodi di Deploy di un Web Service 1. 2. Esistono due modi per effettuare il deploy del servizio: Metodo diretto Metodo semplificato Deploy di un Web Service -Metodo diretto Si posiziona la classe che implementa il servizio in: <TOMCAT_HOME>\webapps\axis\WEB-INF\classes\miopackage\myservice.class Richiede la stesura di un file di deployment del tipo myservice.wsdd. In questo modo si istruisce l’engine di Axis affinché in corrispondenza di una determinata richiesta (sottoforma di messaggio SOAP), istanzi la classe e ne richiami il relativo metodo. Wsdd: Web Service Deployment Descriptor Struttura di un file wsdd (deploy.wsdd): <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="urn:myserviceWS" provider="java:RPC"> <parameter name="className" value="miopackage.myserviceWS"/> <parameter name="allowedMethods" value=“mymethod"/> <parameter name="scope" value="Request"/> </service> </deployment> Deploy di un Web Service -Metodo diretto Contenuto di un file wsdd: Name: indica il nome del servizio web. Provider : java:RPC” indica ad Axis di pubblicare il servizio secondo un meccanismo RPC. Parameter className: indica il nome della classe che implementa il servizio. Parameter allowedMethods: metodi resi disponibili per essere invocati (* indica tutti i metodi della classe). Parameter scope: definisce il ciclo di vita della classe che in questo caso viene istanziata, utilizzata e distrutta ad ogni richiesta, altri valori sono Application e Session. WSDD - Parametro scope 1. 2. 3. <parameter name=“scope” value=“...”> Request: una nuova istanza del servizio per ogni richiesta (default) Application: singolo oggetto condiviso da tutte le richieste Session: un oggetto per ogni sessione Tipi di chiamate RPC-based:chiamate a metodo remote realizzate attraverso un protocollo basato su XML. Document-based:scambio di oggetti attraverso documenti XML. Wrapped:come document-based ma gli oggetti sono rappresentati attraverso i loro attributi costituenti invece che attraverso strutture complesse. Message-based:scambio di arbitrari documenti XML. Chiamate di tipo RPC In una interazione di tipo RPC, il web service è visto come una singola applicazione o come un unico componente con i dati incapsulati. Interazione di tipo document-based In una interazione di tipo document-based, il service consumer interagisce con il servizio utilizzando docuemnti che devono essere processati come entità complete. Web Service - Interoperabilità In teoria, diverse implementazioni SOAP possono interagire. In pratica, sono necessari degli accorgimenti legati alla corrispondenza tra i tipi WSDL e i tipi specifici del linguaggio adottato. Corrispondenza fra tipi AXIS - Tipi di dato Non si possono inviare oggetti per i quali non esista un “AXIS Serializer” registrato. AXIS fornisce il Bean Serializer per la serializzazione dei JavaBean. Per poter trasmettere oggetti arbitrari dobbiamo costruire e registrare altri Serializer SOAP non supporta il passaggio di riferimenti remoti. AXIS - Bean serializer Le classi che rispettano la specifica JavaBean possono essere serializzate automaticamente (metodi get/set per tutti i parametri) Esempio: public class Order { private String customerName; private String shippingAddress; public String getCustomerName() { return customerName; } public void setCustomerName(String name) { customerName = name; } public String getShippingAddress() { return shippingAddress; } public void setShippingAddress(String address) { shippingAddress = address; }} AXIS - Bean serializer Bisogna specificare il mapping tra un XML QName e il JavaBean perché AXIS riesca a serializzarlo. Il mapping si specifica con li seguente elemento del WSDD: <beanMapping qname=“ns:local” xmlns:ns=“someNamespace” languageSpecificType=“java:my.java.thingy” /> L’associazione realizzata è la seguente my.java.thingy <-> someNamespace:local Custom serializer Bisogna implementare un Serializer ed un Deserializer. Devono essere indicati nel WSDL attraverso l’elemento <typeMapping...>. Deploy di un Web Service -Metodo diretto 1. Per effettuare il deploy: Aggiungere al classpath le seguenti classi: • axis.jar • jaxrpc.jar • saaj.jar • commons-logging.jar • commons-discovery.jar • log4j-1.2.8.jar 2. Lanciare il comando: java org.apache.axis.client.AdminClient deploy.wsdd La classe AdminClient eseguirà il deployment leggendo i metadati dal file deploy.wsdd indicato comunicandoli automaticamente all’Axis engine. Deploy di un Web Service - Il comando AdminClient Di seguito è mostrata la sintassi da usare per pubblicare il servizio da riga di comando. Da notare che si è assunto che le variabili di sistema, PATH e CLASSPATH, siano settate correttamente. Deploy di un Web Service -Metodo diretto Controllare la presenza del nuovo servizio: http://localhost:8080/axis/servlet/AxisServlet Deploy di un Web Service -Metodo alternativo Utilizzo dell’estensione JWS (Java Web Service) La classe java che implementa il servizio viene automaticamente tradotta da AXIS che pubblicherà il WSDL corrispondente. I servizi deployati in questo modo non vengono visualizzati nella lista dei servizi all’URL http://localhost:8080/axis/servlet/AxisServlet Per controllarne l’esistenza si deve puntare il browser all’indirizzo del WSDL Es. http://localhost:8084/axis/myserviceWS.jws?WSDL Deploy di un Web Service -Metodo alternativo 1. 2. 3. 4. Passi da compiere: Si parte dalla classe Java (file .java) Si rinomina il file in .jws Si posiziona il file in TOMCAT_HOME/webapps/axis Si riavvia Tomcat affinchè effettui tutte le operazioni di deploy ESEMPI PRATICI Esempio 1 - Creazione del servizio //File Esempio1.java package miopackage; /* Classe che implementa il servizio. */ public class SalutoWS{ /* Metodo che implementa il servizio. * Questo servizio restituisce una stringa di saluto. **/ public String saluto(String nome) { return “Ciao “+ nome + ” ! ”} ; } - Copiamo il file in: <TOMCAT_HOME>\webapps\axis\WEBINF\classes\miopackage\SalutoWS.class Prepariamo il file per il deployment Eseguire il comando AdminClient per pubblicare il servizio Cotrollare l’URL del nuovo servizio Esempio 1 - Creazione di un Client Ora che abbiamo creato il Web Service non ci rimane che creare un Client che lo utilizzi. Il tutto è molto semplice perchè si riduce a richiamare il metodo passando due parametri e ricevere la risposta, il tutto utilizzando le classi che ci offre Axis. Esempio 1 - Creazione di un Client 1. 2. 3. Il Client si realizza facendo uso dell’interfaccia Call della classe Service che fornisce un’istanza di tale classe. Inoltre è necessario tramite la lettura del WSDL: L’URL del servizio Il nome del servizio I parametri d’ingresso e di uscita Esempio 1 - Creazione di un Client import (vari) public class ClientSalutoWS { public static void main(String[] args) { String messaggio = ""; try { Call call = (Call) new Service().createCall(); call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/")); call.setOperationName(new QName("SalutoWS", "saluto")); Object rispostaWS = call.invoke(new Object[]{"Giuseppe"}); messaggio = "il Web service ha risposto: "+(String) rispostaWS;} catch (MalformedURLException ex) { messaggio = "errore: l'url non è esatta"; }catch (ServiceException ex) { messaggio = "errore: la creazione della chiamata è fallita"; }catch (RemoteException ex) { messaggio = "errore: l'invocazione del WS è fallita"; }finally{ System.out.println(messaggio); } } } Nomi dei parametri Nelle chiamate SOAP i nomi dei parametri sono indicati con arg0, arg1, ... Con le seguenti isruzioni: call.addParamater(<nomePar>, <tipo>, <IN/OUT>) call.setReturnType(<tipo>) è possibile definire nomi e tipi delle variabili setReturnType è necessario nei casi in cui la risposta SOAP non riporti l’indicazione del tipo ritornato Ad esempio: <result>Hello!</result> invece di <result xsi:type=“xsd:string”>Hello!</result> Esempio 1 – Messaggio SOAP Request POST /axis/services/ HTTP/1.0 Content-Type: text/xml; charset=utf-8 Accept: application/soap+xml, application/dime, multipart/related, text/* User-Agent: Axis/1.1 Host: 127.0.0.1 Cache-Control: no-cache Pragma: no-cache SOAPAction: "" Content-Length: 442 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/ xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <ns1:saluto soapenv:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ xmlns:ns1="urn:SalutoWS"> <ns1:arg0 xsi:type="xsd:string">Giuseppe</ns1:arg0> </ns1:saluto> </soapenv:Body> </soapenv:Envelope> Esempio 1 – Messaggio SOAP Response HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Connection: close Date: Fri, 21 Nov 2003 16:10:50 GMT Server: Apache Tomcat/4.0.4-b2 (HTTP/1.1 Connector) <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <ns1:salutoResponse soapenv:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ xmlns:ns1="urn:SalutoWS"> <ns1:salutoReturn xsi:type="xsd:string">Ciao Giuseppe!</ns1:salutoReturn> </ns1:salutoResponse> </soapenv:Body> </soapenv:Envelope> Esercizio Realizzare un web service che implementi una semplice calcolatrice (+,-,*,/). Realizzare il WSDD relativo. Realizzare un client che invochi il servizio.