Upload
dothien
View
241
Download
0
Embed Size (px)
Citation preview
JAX-WSJAX-WS
Java API for Java API for XML Web ServicesXML Web Services
Massimo Martinelli
Consiglio Nazionale delle Ricerche - CNRIstituto di Scienza e Tecnologie della Informazione - ISTI
29/05/2010, Area Ricerca CNR, Pisa
Il corso di Java Web Services in 1 Minuto!
import ...
public class MioWebService {
public String ciao(String nome) {
return “Ciao “+ nome; }
}
@WebService
@WebMethod
Scriviamo una classe Java con un metodo
Aggiungiamo metainformazioni
Finito! ...
JAX-WSJAX-WS
Java API for Java API for XML Web ServicesXML Web Services
Massimo Martinelli
Consiglio Nazionale delle Ricerche - CNRIstituto di Scienza e Tecnologie della Informazione - ISTI
RIPARTIAMO :-)RIPARTIAMO :-)
Sommario Cosa è JAX-WS?
Implementazione di Web Service e di Client
Tipi di dato supportati da JAX-WS
JAXB
Esercizi da svolgere durante il corso
Secondo il W3C ...Un Web Service è un sistema software designato a supportare interazioni interoperabili macchina-macchina su una rete.
Ha una interfaccia descritta in un formato elaborabile da una macchina (specificamente WSDL).Altri sistemi interagiscono con il Web Service in un modo prescritto dalla sua descrizione usando messaggi SOAP, tipicamente convogliati usando HTTP con una serializzazione XML insieme ad altri standard Web.
Cosa è JAX-WS acronimo di
“Java API for XML Web Services” Tecnologia per realizzare Web Service e
client in Java che comunicano utilizzando messaggi SOAP-XML
L’implementazione di riferimento (JAX-WS for Reference Implementation) è un progetto open source e fa parte del progetto GlassFish, un application server Java EE.
Fa parte della distribuzione “Metro”
Web Services semplificati
Da Java 5 (Java 1.5) introdotte le annotazioni
ovvero dei Metadati sul codice Java
Esempio di annotazione:
@Annotazione
Annotazioni:
– Possono essere trattate a livello di compilazione
– Possono essere trattate anche tempo di esecuzione
Annotazioni nei Web Service
Per sviluppare un Web Service con JAX-WS è necessario utilizzare l'annotazione javax.jws.WebService
Ovvero: la classe che implementa il Web Service deve essere annotata con la annotazione javax.jws.WebService (o con javax.jws.WebServiceProvider)
Service Endpoint Interface (SEI) Una interfaccia service endpoint (SEI) è una interfaccia Java
che dichiara i metodi che un client può invocare sul servizio
SEI non necessaria quando si implementa un endpoint JAX-WS: la classe di implementazione del Web Service (SIB Service Implementation Bean) definisce implicitamente una SEI
può riferire esplicitamente una SEI tramite l’elemento endpointInterface dell’annotazione @Webservice
Preparazione agli esercizi
Creare una directory LINUX ~home/java-pgm/
C:/java-pgm/
dove installeremo i programmi che seguono...
Strumenti che utilizzeremo: Java SE 6
Java Standard Development Kit versione 6
(Se non è già installata eseguire da terminale il comando java –version )
Scaricare da http://java.sun.com/javase/downloads/index.jsp
Netbeans è un ambiente di sviluppo realizzato da SUN
◦ Scaricare da http://netbeans.org/downloads/index.html
(versione “Java” o “All”)
Strumenti che utilizzeremo: Netbeans
Strumenti che utilizzeremo: Glassfish
Application server open source realizzato da Sun di riferimento per Java EE 5/6.
Incluso con NetBeans
Supporta: EJB 3.1 JPA 2 JAXB 2.x JAX-WS 2.x
Per utilizzare con Tomcat
scaricare ant da http://ant.apache.org/ scaricare metro da http://metro.dev.java.net/
java -jar metro*.jar
ant -Dtomcat.home=<DirectorydiTomcat> -f metro-on-tomcat.xml install
V
Implementazione di un Web Service (classe Java): Passi Base
1. Codificare la classe che implementa il servizio
2. Compilare tale classe
3. Dispiegare (deploy) il file WAR
4. Codificare la classe per il client
5. Utilizzare wsimport per generare e compilare gli artefatti
6. Compilare la classe client
7. Eseguire il client
Codifica della classe SIB (1/2)
package serviziociao;
import javax.jws.WebService;
@WebServicepublic class Ciao {
private String messaggio = new String("Ciao, ");
public void Ciao() {}
@WebMethodpublic String saluto(String nome) {
return messaggio + nome + ".";}
}
Codifica della classe SIB (2/2)
• La classe implementata, Ciao, è annotata come web service utilizzando l'annotazione @WebService
• Ciao dichiara un singolo metodo chiamato saluto, annotato con l'annotazione @WebMethod
• La classe implementata deve anche definire un costruttore di default public senza argomenti
JAX-WS Endpoint I metodi della classe che implementa il Web Service devono essere public, e non devono essere dichiarati ne static ne final
I metodi di Business esposti ai client dei Web service devono:
essere annotati con javax.jws.WebMethod
avere tipi di parametri compatibili con JAX-B
Le classi che implementano i Web Service
Non devono essere dichiarate abstract
Devono avere un costruttore di default public
Non devono definire il metodo finalize
Possono usare le annotazioni javax.annotation.PostConstruct o javax.annotation.PreDestroy sui propri metodi per gestire il loro ciclo di vita
Il medoto @PostConstruct è chiamato dal container prima che la classe di implementazione inizi a rispondere ai client del Web Service
Il metodo @PreDestroy è chiamato dal container prima che l'endpoint sia rimosso dall'operazione
Esercizio (Guidato)
• Realizzare un Web Service che fa la somma di due numeri interi
• Da Netbeans creare un nuovo progetto Web
• Creare un nuovo Web service
• Dispiegare, eseguire e provare (Test)
Non vi avevo detto che bisognava importare anche ...
package serviziociao.endpoint;
import javax.jws.WebService;import javax.jws.WebMethod;
@WebService()public class Ciao {
private String messaggio = new String("Ciao, ");
public void Ciao() {}
@WebMethod()public String saluto(String nome) {
return messaggio + nome + ".";}
}
@WebServiceAttributi● name: nome del wsdl:portType (per difetto il nome della classe Java senza package)
● portName: nome del wsdl:portName (per difetto è il nome del WebService concatenato a Port)
● serviceName: nome del servizio (wsdl:service) (per difetto il nome della classe concatenato alla Stringa “Service”)
● endpointInterface: (es. endpointInterface = "package.MioWebServiceInterface") specifica il nome completo della SEI (per difetto la classe java,comprensiva del package, concatenata alla Stringa “ServicePortType”)
● targetNamespace: namespace di riferimento per il WSDL e gli XML generati (per difetto è il nome del package java)
● wsdlLocation: l'indirizzo documento WSDL del Web Service. L'indirizzo può essere relativo o assoluto.
[email protected] (serviceName = "NomeServizio", endpointInterface = "it.cnr.NomeServizioServicePortType", targetNamespace="http://..../", portName="NomeServizioServicePort")
V
@WebMethodPer difetto tutti i metodi public di una classe annotata con @WebService vengono esposti nel Web ServicePer personalizzare un metodo esposto come operazione WS si utilizza @WebMethodAttributi
− action definisce l'azione per l'operazione. (per difetto = al nome del metodo )− exclude specifica se il metodo va escluso dalla pubblicazione del Web Service.
(per difetto=”false”) (Booleano)− operationName specifica il nome di wsdl:operation per il metodo (per difetto =
nome del metodo)
@WebMethod(action="somma")public int somma(@WebParam(name = "i") int i,
@WebParam(name = "j") int j) { int k = i + j; return k;
}
V
@WebParam e @WebResult
personalizzazione dei parametri di input(@WebParam) e di output(@WebResult) di un metodo del Web Service
Attributi● header: Specifica se il parametro si trova in un'intestazione di messaggio anziché nel corpo. Per difetto è false. (Booleano)
● mode: WebParam.mode.IN parametro, WebParam.mode.OUT, WebParam.mode.INOUT che rappresentano parametri in input, in output e parametri ripetuti sia in input che in output
● name: nome del parametro.
● targetNamespace:spazio dei nomi XML dell'elemento XML per il parametro
V
@SOAPBinding
In caso i metodi del Web Service utilizzino tipi semplici come String o int è possibile utilizzare
la seguente annotazione@SOAPBinding(style=Style.RPC)
In caso di utilizzo di tipi complessi lo stile da utilizzare corrisponde a quello di default:
@SOAPBinding(style=Style.DOCUMENT)
Nel secondo caso vedremo più avanti come utilizzare il mapping (da oggetti Java in XML e
viceversa) con JAXB
@SOAPBinding specifica come avviene il mapping a livello SOAP
Attributi– style
stile di codifica per messaggi inviati e ricevuti. Valori: DOCUMENT (default), RPC.
– useformattazione per messaggi inviati e ricevuti. Valori LITERAL(default). ENCODED (non WS-I standard)
– parameterStylevalori Wrapped (default) o BARE (utilizzabile solo in stile DOCUMENT)
Esempio:@WebService(targetNamespace = "http://.....", name = "MioServizio")
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
@SOAPBindingIndipendenza dal Protocollo e dal Trasporto
Personalizzazione tramite Annotazioni
@WebService(name=”SistemaInformativoService”, targetNamespace=”http://esempio.it”)
public class SistemaInformativo {
...
@WebMethod(operationName=”getPersona”)
public Persona getPersona(@WebParam(name=”codicefiscale”) String codicefiscale) {
// ... codice di implementazione ...
}
}
Implementazione del Servizio(da classe Java)
Al momento dell'esecuzione Netbeans genera automaticamente gli artefatti, compila tutte le classi, dispiega il servizio e attiva l’application server
Dietro le quinte il Web Service (endpoint) viene generato dal tool wsgen
wsgen cp ./build -keep -s ./src -d ./build package.Class
Artefatti
Il tool “wsimport” a partire dal WSDL crea le classi di supporto (artefatti):• Service Endpoint Interface (SEI)• Service• Exception class a partire da wsdl:fault• Oggetti generati a partire dagli schemi XML (JAXB...)
Per invocare una operazione WS è necessario istanziare la classe service ed ottenere il proxy mediante chiamata al metodo:
get<ServiceName>PortCalculatorService svc = new CalculatorService();Calculatorproxy = svc.getCalculatorPort( ) ;int answer = proxy.somma(35, 7);
wsimport
Parametri: wsdl: percorso del file wsdl (es: /home/massimo/servizio.wsdl, http://www..../servizio.wsdl, ...) destdir: destinazione dei compilati generati sourcedestdir: destinazione dei sorgenti generati keep: se indicata mantiene i sorgenti generati verbose: dettaglio verboso delle operazioni svolte binding: specifica il tipo di collegamento package: nome del package per le classi generate
Prova del Servizio ...senza un Client
• Aprire Admin Console collegandosi col browser all'indirizzo http://localhost:4848/
• Fornire utente e password per effetturare il login
• Cliccare su “Web Services” nel panello a sinistra
• Cliccare Hello
• Cliccare Test(http://localhost:8080/EsempioWSCiao/CiaoService?Tester)
Prova del metodo “sayHello”
•in “Methods”, scrivere un nome come parametro per il metodo “sayHello”•Cliccare il pulsante “sayHello”
Implementazione di un servizioa partire da un WSDL
Netbeans genera un Web Service (bozza) a partire da un WSDL
Dietro le quinte esegue per noi il comando wsimport
wsimport -keep –s <directory_sorgenti> -d <classi_generate_compilate> <percorso_documento_WSDL>
-keep non cancella i file sorgenti generati
Il comando genera eventuali artefatti JAXB per gestire tipi non di base
Codifica del Client1. Utilizzare l’annotazione
javax.xml.ws.WebServiceRef per riferire un Web Service
• L’attributo wsdlLocation specifica l’ URI del documento WSDL@WebServiceRef{wsdlLocation=“http://localhost:8080/EsempioWSCiao/CiaoService?wsdl}
2. Invocare il metodo del Web Service utilizzando il proxy (port) del service
Hello port = service.getCiaoPort();
3. Invocare il metodo (saluto ) del proxy (port)
ClientCiao package simpleclient;
import javax.xml.ws.WebServiceRef;import helloservice.endpoint.HelloService;import serviziociao.endpoint.Ciao;
public class ClientCiao {@WebServiceRef(wsdlLocation="http://localhost:8080/EsempioWSCiao/CiaoService?wsdl") static CiaoService service = new CiaoService();public static void main(String[] args) {
try {ClientCiao client = new ClientCiao();client.doTest(args);
} catch(Exception e) {e.printStackTrace();
}}public void doTest(String[] args) {
try {System.out.println(“Recupero il proxy (port) dal servizio: " + service);Ciao port = service.getCiaoPort();System.out.println("Invoco l’operazione saluto sul proxy (port)");String name;if (args.length > 0) {
nome= args[0];} else {
nome = “Nessun nome";}String response = port.saluto(nome);System.out.println(response);
} catch(Exception e) {e.printStackTrace();
}}
Esercizio
• Preparare un client che chiami il metodo “registraNome” del Web Service “WSnominativo” descritto dal WSDL che trovate all’indirizzo
• http://.......:8080/EsercizioWSserver/WSnominativoService?wsdl
• il metodo richiede in input un parametro di tipo String
• Test: http://....:8080/EsercizioWSserver/WSnominativoService?Tester
• Controllo accessi: http://.....:8080/EsercizioWSserver/
Tipi Supportati da JAX-WS• Per essere indipendenti dal linguaggio i tipi supportati sono
limitati a quelli descritti nelle specifiche:
• tipi atomici (es. int, boolean, ecc.)
• String
• array e List
• semplici JavaBean usati come strutture (con costruttore public)
JAX-WS delega a JAXB il collegamento tra tipi Java e XML (e viceversa).
Sviluppatori non devono preoccuparsi del collegamento (in generale)
JAXB
Java API XML BindingLibrerie che consentono di collegare (binding) oggetti Java a documenti XMLA partire da un documento XML schema si può creare una classe Java corrispondente le cui istanze possono leggere/scrivere documenti XMLe viceversa
Marshalling / Serializzazione
Il procedimento detto marshalling si riferisce alla possibilità di serializzare (..trasformare..) oggetti Java in documenti XML.
A partire da un oggetto Java, schemagen crea un documento XML corrispondente
schemagen [-opzioni ...] [sorgenti_java]
Le istanze di queste classi possono essere collegate ai relativi documenti XML
Unmarshalling / Deserializzazione
Il procedimento detto unmarshalling si riferisce alla possibilità di deserializzare (..trasformare..) documenti XML (schema) in oggetti Java.
A partire da un documento XML Schema xjc crea un oggetto Java corrispondente
xjc [-opzioni ...] <schema>xjc biblioteca.xsd
Le istanze di questa classe possono essere collegate a documenti XML
Esempio @XMLRootElementpublic class Persona () { private String nominativo; private String identificatore;
public Persona() { }
public void getNominativo(){return nominativo;
}
public void setNominativo(String nominativo){this.nominativo=nominativo;
}
public int getIdentificativo() { return identificativo; } @XmlAttribute // identificatore attributo dell'elemento radice public void setId(int identificatore) { this.identificatore = identificatore; }}
JAXB Serializzare e Deserializzare// Serializzare un oggetto in XMLPersona persona= new Persona();persona.setNominativo("Salvo Montalbano");persona.setIdentificatore(“slvmnt);
// creiamo il contesto JAXB e un marshaller (serializzatore)JAXBContext contesto = JAXBContext.newInstance(Persona.class);Marshaller serializzatore = contesto.createMarshaller();// Impostiamo un formato “pretty” serializzatore.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// serializzaimoserializzatore.marshal(persona, new File("/output.xml"));
// Deserializzare (Ottenere l'oggetto dall'XML// creiamo il contesto JAXB e un unmarshaller (deserializzatore)JAXBContext contesto = JAXBContext.newInstance(Persona.class);Unmarshaller deserializzatore = contesto.createUnmarshaller();// otteniamo l'oggettoMessage msg = (Persona)deserializzatore.unmarshal(new File("/persona.xml"));
Personalizzazione
@XMLTypepublic class Persona () { private String nominativo; private String identificatore;
....}
@XMLRootElementpublic Dipendente() { }
Persona persona; }
}
Esempio public class Persona () { private String nominativo; private String identificatore;
@XMLRootElement public Persona() { }
public void getNominativo(){return nominativo;
}
public void setNominativo(String nominativo){this.nominativo=nominativo;
}
public int getIdentificativo() { return identificativo; } @XmlAttribute // identificatore attributo dell'elemento radice public void setId(int identificatore) { this.identificatore = identificatore; }}
Gestire gli allegati (attachment): Server
@MTOM(threshold = 4096)@WebServicepublic class WSUpload {
public void fileUpload(String nomeFile, @XmlMimeType("application/octet-stream") DataHandler data) { try { DataHandler dh = data; File file = new File(nomeFile); FileOutputStream outputStream = new FileOutputStream(file); dh.writeTo(outputStream);
} catch (Exception e) { throw new WebServiceException(e); } }
}
Gestire gli allegati (attachment): Client
WSUploadService service = new WSUploadService(); // classe generataMTOMFeature feature = new MTOMFeature();WSUpload port = service.getWSUploadPort(feature); //classe generata
URL url = new URL("file:///home/massimo/prova.png");DataHandler dh = new DataHandler(url);String nomefile = "prova.png";port.fileUpload(nomefile, dh);
Esercizio
• Preparare un client che chiami il metodo YYYYY del Web Service XXXX descritto dal WSDL che trovate all’indirizzo
• http://......:8080/EsempioWSUpload/WSUploadService?wsdl
• il metodo richiede in input un parametro di tipo String e un parametro file corrispondente ad una immagine jpg o gif o png che avete sul vostro disco
Novità introdotta con in Java SE 6//pubblicazione di un POJO (Plain Ordinary Java Object) @WebService public class Calcolatore { @Resource WebServiceContext context; // ottiene dal server il contesto dei WS public int somma(int a, int b) { return a+b; } }
// crea e pubblica un endpointCalcolator calculatore = new Calcolatore();Endpoint endpoint=Endpoint.publish(“http://localhost/calcolatore”,Calcolatore);
// WSDL creato e pubblicato al volo: http://localhost/calcolatore?WSDL
// assegnazione di protocollo (per difetto è HTTP)// Endpoint endpoint=Endpoint.create(SOAPBinding.SOAP12HTTP_BINDING,calcolatore);//endpoint.publish(“http://localhost/calcolatore”);
Client Asincroni (nonblocking)
class AmazonAsyncClient { public static void main(String[ ] args) { // Usage if (args.length != 1) { System.err.println("Usage: java AmazonAsyncClient <access key>"); return; } final String access_key = args[0]; // Create service and get portType reference. AWSECommerceService service = new AWSECommerceService(); AWSECommerceServicePortType port = service.getAWSECommerceServicePort(); // Create request. ItemSearchRequest request = new ItemSearchRequest(); // Add details to request. request.setSearchIndex("Books"); request.setKeywords("quantum gravity"); ItemSearch item_search= new ItemSearch(); item_search.setAWSAccessKeyId(access_key); item_search.getRequest().add(request); port.itemSearchAsync(item_search, new MyHandler()); // In this case, just sleep to give the search process time. // In a production application, other useful tasks could be // performed and the application could run indefinitely. try { Thread.sleep(400); } catch(InterruptedException e) { System.err.println(e); } }
// The handler class implements handleResponse, which executes // if and when there's a response. static class MyHandler implements AsyncHandler<ItemSearchResponse> { public void handleResponse(Response<ItemSearchResponse> future) { try { ItemSearchResponse response = future.get(); List<Items> item_list = response.getItems(); for (Items next : item_list) for (Item item : next.getItem()) System.out.println(item.getItemAttributes().getTitle()); } catch(InterruptedException e) { System.err.println(e); } catch(ExecutionException e) { System.err.println(e); } } }}
• Metro User Guide https://metro.dev.java.net/guide/index.html• Java Web Services Developer Pack 2.0•http://java.sun.com/webservices/downloads/webservicespack.html•Java EE 5 Developing using Glassfish Application Server. David R. Heffelfinger - Packt Publishing•Create stand-alone Web services applications with Eclipse and Java SE 6. Fiona Lam, John Robertson, IBM developerWorks•Documentazione di WebSphere Application Server http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.wsfep.multiplatform.doc/info/ae/ae/rwbs_jaxwsannotations.html•RESTful Web services: The basics. Alex Rodriguez - IBM developerWorks•Web Services con Java5. MokaByte 127, 128 - Marzo Aprile 2008 (http://www.mokabyte.it/)•Java & XML. Brett McLaughlin – O'Reilly•Java Web Services Up adn Running – O'Reilly•Corso Comune Livorno “Web Services”. M.Martinelli•Corso Comune Livorno “AXIS 2.1”. M.Martinelli•Corso Comune Livorno “Java e XML”. M.Martinelli
Bibliografia