Your SlideShare is downloading. ×
Lezione 10: Web Service in Java (2)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Lezione 10: Web Service in Java (2)

3,421

Published on

✦ I tipi di dato utilizzabili …

✦ I tipi di dato utilizzabili
✦ Parametri di uscita e ingresso/uscita
✦ Servizi stateless e stateful

Published in: Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,421
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
0
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Lezione 10: Web Service in Java (2) Corso di Programmazione in Rete Laurea Magistrale in Ing. Informatica Università degli Studi di Salerno 1
  • 2. Outline ✦ I tipi di dato utilizzabili ✦ Parametri di uscita e ingresso/uscita ✦ Servizi stateless e stateful 2
  • 3. I tipi di dato utilizzabili ✦ Poiché i WS devono essere indipendenti dal linguaggio, introducono delle limitazioni più forti rispetto a RMI sui tipi di dato utilizzabili per i parametri e i valori di ritorno 3
  • 4. I tipi di dato utilizzabili ✦ Il mapping tra i tipi definiti in WSDL e i tipi di Java non è univoco, ma dipende dalla specifica libreria usata per i WS • Faremo riferimento al mapping di JAX-WS ✦ Alcune librerie consentono di personalizzare il mapping quando la corrispondenza di default non è appropriata 4
  • 5. I tipi di dato utilizzabili ✦ I tipi utilizzabili sono ristretti a: • tipi atomici (es. int, boolean, ecc.) • String • array e List • semplici JavaBeans usati come strutture 5
  • 6. Array e liste ✦ È possibile usare array il cui tipo base sia tra quelli citati ✦ È possibile utilizzare List<T> se il tipo T è tra quelli citati ✦ Negli stub, i parametri/valori di ritorno di tipo array vengono comunque convertiti in List<T> 6
  • 7. Oggetti ✦ È possibile usare dei semplici JavaBeans a condizione che abbiano un costruttore pubblico senza argomenti ✦ Vengono trasmessi solo: • campi pubblici appartenenti a tipi utilizzabili • proprietà accessibili attraverso coppie di metodi che seguono la convenzione di naming getXxxx() e setXxxx(), se il valore appartiene a un tipo utilizzabile 7
  • 8. Oggetti ✦ NOTA BENE • gli stub generati non usano la stessa classe definita nel server, ma una nuova classe con lo stesso nome che rende accessibili le proprietà con coppie di metodi getXxxx e setXxxx • la classe definita dagli stub (e quindi vista dal client) non contiene gli eventuali altri metodi presenti nella classe usata dal server, né i campi che non rientrano nelle condizioni viste precedentemente • in altre parole, gli oggetti utilizzabili si comportano come Data Transfer Objects: semplici contenitori di dati, a cui non sono associati 8 comportamenti
  • 9. Oggetti ✦ Esempio: sul server package myservice; public class Dimension { public int width; public int height; } package myservice; import javax.jws.*; @WebService public class MyService { public Dimension getDim() { Dimension dim=new Dimension(); dim.width=800; dim.height=600; return dim; } // etc etc etc 9
  • 10. Oggetti ✦ Esempio: sul client package client; import client.stub.*; public class TestClient { public static void main(String args[]) { MyServiceService service=new TestService(); MyService test=service.getPort(MyService.class); Dimension dim=test.getDim(); int width=dim.getWidth(); // NOTA: non posso usare dim.width ! } } 10
  • 11. I tipi di dato utilizzabili ✦ Non è possibile usare direttamente come parametro/valore di ritorno il riferimento a un oggetto remoto • vedremo successivamente un modo per aggirare (in parte) questa limitazione 11
  • 12. Parametri di uscita e ingresso/uscita ✦ In linguaggi diversi da Java i parametri possono essere anche di uscita e di ingresso/uscita, usando il meccanismo del passaggio per riferimento ✦ Perciò operazioni definite in un WS possono anche avere parametri di uscita o di ingresso/uscita • occorre un meccanismo per rappresentare questi parametri in Java 12
  • 13. La classe Holder<T> ✦ La classe Holder<T> definita nel package javax.xml.ws è usata per rappresentare un parametro di tipo T ✦ Holder ha un campo pubblico value, che contiene il valore del parametro • per i parametri di uscita, il metodo deve assegnare un valore al campo value • per i parametri di ingresso/uscita, il metodo può usare il valore iniziale di value e può modificarlo • in entrambi i casi, il nuovo valore di value verrà trasmesso al client 13
  • 14. L’annotazione @WebParam ✦ Nella classe che implementa il servizio occorre indicare che il parametro è di uscita o ingresso/uscita con le seguenti annotazioni: • @WebParam(mode=WebParam.Mode.OUT) • @WebParam(mode=WebParam.Mode.INOUT) 14
  • 15. Esempio ✦ Il server: package myservice; import javax.jws.*; import javax.xml.ws.*; @WebService public class Location { public void getCoordinates( @WebParam(mode=WebParam.Mode.OUT) Holder<Double> longitude, @WebParam(mode=WebParam.Mode.OUT) Holder<Double> latitude) { longitude.value = -13.7; latitude.value = 41.1; } } 15
  • 16. Esempio ✦ Il client: package client; import client.stub.*; import javax.xml.ws.Holder; public class TestLocation { public static void main(String args[]) { LocationService service=new LocationService(); Location loc=service.getPort(Location.class); Holder<Double> longitude=new Holder<Double>(); Holder<Double> latitude=new Holder<Double>(); loc.getCoordinates(longitude, latitude); System.out.println("Long: "+longitude.value); System.out.println("Lat: "+latitude.value); } } 16
  • 17. Servizi stateless ✦ In JAX-WS gli oggetti che implementano un servizio sono considerati “stateless” • una singola istanza dell’oggetto serve le richieste di tutti i client • l’oggetto non può mantenere implicitamente traccia della conversazione con un singolo client ‣ Esempio: l’oggetto che implementa il service non può sapere se il client che fa una richiesta ha già effettuato una qualche forma di login, a meno che questa informazione non sia passata come parametro dal client stesso 17
  • 18. Gestione delle sessioni ✦ Fino alla versione 2.1 di JAX-WS per mantenere una forma di stato associato a una sessione di lavoro c’erano due alternative: • usare un parametro esplicito per identificare la sessione in tutte le operazioni • usare meccanismi legati al sottostante meccanismo di trasporto (es. HttpSession) 18
  • 19. Gestione delle sessioni ✦ Usare un parametro esplicito per identificare la sessione • semplice da implementare ‣ al momento della prima connessione il client riceve (eventualmente a seguito di una verifica di identità) un identificatore della sessione di lavoro ‣ ogni altra richiesta prevede che il client passi questo identificatore al server ‣ il server usa questo identificatore come chiave in una struttura dati che contiene le informazioni relative alla particolare sessione di lavoro • complica l’interfaccia con il client, che deve aggiungere esplicitamente questo parametro a tutte le operazioni 19
  • 20. Gestione delle sessioni ✦ usare meccanismi legati al livello di trasporto (es. cookie HTTP) • trasparente al client • il server deve accedere a tali meccanismi, perdendo l’indipendenza dal tipo di trasporto utilizzato (es. il server diventa usabile solo con HTTP) 20
  • 21. Servizi stateful ✦ Con JAX-WS 2.1 è stato introdotto il concetto di servizi stateful: • è possibile creare più istanze dell’implementazione del servizio, in modo che un’istanza serva un singolo client • le diverse istanze sono associate alla stessa URL; viene usata l’estensione WS-Addressing del protocollo SOAP, che definisce un Endpoint Reference all’interno del messaggio, per distinguere tra le diverse istanze 21
  • 22. Servizi stateful ✦ Per definire un servizio come stateful bisogna: • annotare il servizio con le annotazioni: ‣ @javax.xml.ws.soap.Addressing ‣ @com.sun.xml.ws.developer.Stateful • definire un campo public static di tipo StatefulWebServiceManager<T>, dove T è la classe che implementa il web service (StatefulWebServiceManager è nel package com.sun.xml.ws.developer) 22
  • 23. Esempio ✦ Supponiamo di voler realizzare un WS per gestire i conti correnti di una banca package myservice; import javax.jws.*; import javax.xml.ws.soap.Addressing; import com.sun.xml.ws.developer.*; @WebService @Stateful @Addressing public class Account { public static StatefulWebServiceManager<Account> manager; private int number; private double balance; public Account(int number) { this.number=number; this.balance=1000; } public synchronized double getBalance() { return balance; } public synchronized void transfer(double amount) { balance+=amount; } 23 }
  • 24. Istanziazione ✦ Per pubblicare un WS stateful occorre usare il metodo export dell’oggetto StatefulWebServiceManager associato al WS • l’oggetto StatefulWebServiceManager viene inserito automaticamente nel campo static della classe • il metodo export restituisce un W3CEndpointReference, che deve essere comunicato al client per poter accedere al WS 24
  • 25. Esempio ✦ Definiamo un WS Bank (stateless) per istanziare i conti correnti package myservice; import javax.jws.*; import javax.xml.ws.wsaddressing.W3CEndpointReference; import java.util.*; @WebService public class Bank { private Map<Integer, Account> accounts=new HashMap<Integer, Account>(); public synchronized W3CEndpointReference getAccount(int number, String password) { if (!"pippo".equals(password)) throw new RuntimeException("Unvalid password!"); Account acc=accounts.get(number); if (acc==null) { acc=new Account(number); accounts.put(number, acc); } return Account.manager.export(acc); } } 25
  • 26. Deployment ✦ Il WS stateful deve essere installato regolarmente, in modo da rendere disponibile il suo WSDL • nell’esempio precedente, occorre installare sia il WS Bank che il WS Account, su due URL diverse 26
  • 27. Accesso a un WS stateful ✦ Il client deve innanzitutto ottenere un W3CEndpointReference per l’istanza del servizio stateful che intende usare ✦ Il client accede al WS passando il W3CEndpointReference come primo parametro del metodo getPort dell’oggetto Service 27
  • 28. Esempio ✦ Accediamo ai nostri conti correnti package client; import client.stub.*; import javax.xml.ws.wsaddressing.W3CEndpointReference; public class TestAccount { public static void main(String args[]) { BankService bankService=new BankService(); Bank bank=bankService.getPort(Bank.class); AccountService accountService=new AccountService(); W3CEndpointReference ref=bank.getAccount(123, "pippo"); Account account=accountService.getPort(ref, Account.class); account.transfer(100); System.out.println("Account 123 balance:" + account.getBalance()); W3CEndpointReference ref2=bank.getAccount(456, "pippo"); Account account2=accountService.getPort(ref2, Account.class); account2.transfer(150); System.out.println("Account 456 balance:" + account2.getBalance()); } } 28

×