29/05/2010, Area Ricerca CNR, Pisa
JAX-WS
Java API for
XML Web Services
Massimo Martinelli
[email protected]
Consiglio Nazionale delle Ricerche - CNR
Istituto di Scienza e Tecnologie della Informazione - ISTI
Il corso di Java Web Services in 1 Minuto!
import ...
Scriviamo una classe Java con un metodo
Aggiungiamo metainformazioni
@WebService
public class MioWebService {
@WebMethod
public String ciao(String nome) {
}
}
return “Ciao “+ nome;
Finito!
...
RIPARTIAMO :-)
JAX-WS
Java API for
XML Web Services
Massimo Martinelli
[email protected]
Consiglio Nazionale delle Ricerche - CNR
Istituto di Scienza e Tecnologie della Informazione - ISTI
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 JAXWS:
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
Strumenti che utilizzeremo: Netbeans
Netbeans è un ambiente di sviluppo realizzato da SUN

◦ Scaricare da
http://netbeans.org/downloads/index.html
(versione “Java” o “All”)
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-ontomcat.xml install
V
Implementazione di un Web Service
A partire da:
una classe Java

un documento WSDL

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;
@WebService
public class Ciao {
private String messaggio = new String("Ciao, ");
public void Ciao() {}
@WebMethod
public 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 + ".";
}
}
@WebService
V
Attributi
● 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.
Esempio
@javax.jws.WebService (serviceName = "NomeServizio", endpointInterface = "it.cnr.NomeServizioServicePortType",
targetNamespace="http://..../", portName="NomeServizioServicePort")
@WebMethod
V
Per difetto tutti i metodi public di una classe annotata con @WebService vengono
esposti nel Web Service

Per personalizzare un metodo esposto come operazione WS si utilizza
@WebMethod

Attributi
− 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;
}
@WebParam e @WebResult
V
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
@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
Indipendenza dal Protocollo e dal Trasporto

@SOAPBinding specifica come avviene il mapping a livello SOAP

Attributi
– style
stile di codifica per messaggi inviati e ricevuti. Valori: DOCUMENT
(default), RPC.
– use
formattazione per messaggi inviati e ricevuti. Valori LITERAL(default).
ENCODED (non WS-I standard)
– parameterStyle
valori Wrapped (default) o BARE (utilizzabile solo in stile DOCUMENT)
Esempio:
@WebService(targetNamespace = "http://.....", name = "MioServizio")

@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use =
SOAPBinding.Use.LITERAL)
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>Port
CalculatorService 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”
•
Analisi dei Messaggi SOAP
Client a partire da un WSDL
Implementazione di un servizio
a 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 Client
1. 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:8
080/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 Binding
Librerie che consentono di collegare (binding) oggetti Java a documenti XML
A partire da un documento XML schema si può creare una classe Java
corrispondente le cui istanze possono leggere/scrivere documenti XML
e 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
xjc crea un oggetto Java corrispondente
XML
Schema
xjc [-opzioni ...] <schema>
xjc biblioteca.xsd
Le istanze di questa classe possono essere collegate a documenti XML
Esempio
@XMLRootElement
public 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 XML
Persona 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);
// serializzaimo
serializzatore.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'oggetto
Message msg = (Persona)deserializzatore.unmarshal(new File("/persona.xml"));
Personalizzazione
@XMLType
public class Persona () {
private String nominativo;
private String identificatore;
....
}
@XMLRootElement
public 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)
@WebService
public 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 generata
MTOMFeature 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 endpoint
Calcolator 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);
// The handler class implements handleResponse, which executes
item_search.getRequest().add(request);
// if and when there's a response.
port.itemSearchAsync(item_search, new MyHandler());
static class MyHandler implements AsyncHandler<ItemSearchResponse> {
// In this case, just sleep to give the search process time.
public void handleResponse(Response<ItemSearchResponse> future) {
// In a production application, other useful tasks could be
try {
// performed and the application could run indefinitely.
ItemSearchResponse response = future.get();
try {
List<Items> item_list = response.getItems();
Thread.sleep(400);
for (Items next : item_list)
}
for (Item item : next.getItem())
catch(InterruptedException e) { System.err.println(e); }
System.out.println(item.getItemAttributes().getTitle());
}
}
catch(InterruptedException e) { System.err.println(e); }
catch(ExecutionException e) { System.err.println(e); }
}
}
}
Bibliografia
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_jaxwsannotatio
ns.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
•
Grazie !