Servizi Web in Java SE, Parte 2: creazione di servizi Web SOAP
JAX-WS supporta i servizi Web basati su SOAP. La parte 2 di questa serie in quattro parti sui servizi Web Java SE definisce un servizio Web di conversione delle unità basato su SOAP, crea e quindi verifica questo servizio Web localmente tramite il server HTTP leggero predefinito (discusso nella Parte 1), interpreta il documento WSDL del servizio e accede al servizio da un semplice client.
Definizione di un servizio web di conversione di unità
Il servizio Web di conversione delle unità, che ho chiamato UC, è costituito da quattro funzioni per la conversione tra centimetri e pollici e tra gradi Fahrenheit e gradi Celsius. Sebbene questo esempio possa essere progettato come una singola classe Java, ho scelto di seguire le migliori pratiche progettandolo come un'interfaccia Java e una classe Java. Il Listato 1 presenta l' UC
interfaccia del servizio Web .
Listato 1. Service Endpoint Interface del servizio Web UC
package ca.javajeff.uc; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface UC { @WebMethod double c2f(double degrees); @WebMethod double cm2in(double cm); @WebMethod double f2c(double degrees); @WebMethod double in2cm(double in); }
UC
descrive una SEI (Service Endpoint Interface) , che è un'interfaccia Java che espone le operazioni di un'interfaccia del servizio Web in termini di metodi Java astratti. I client comunicano con i servizi Web basati su SOAP tramite i propri SEI.
UC
viene dichiarato SEI tramite l' @WebService
annotazione. Quando viene annotata un'interfaccia o una classe Java @WebService
, tutti i public
metodi i cui parametri, valori restituiti ed eccezioni dichiarate seguono le regole definite nella Sezione 5 della specifica JAX-RPC 1.1 descrivono le operazioni del servizio Web. Perché solo public
i metodi possono essere dichiarati nelle interfacce, la public
parola riservata non è necessario quando si dichiara c2f()
, cm2in()
, f2c()
, e in2cm()
. Questi metodi sono implicitamente public
.
Ogni metodo è anche annotato @WebMethod
. Sebbene @WebMethod
non sia essenziale in questo esempio, la sua presenza rafforza il fatto che il metodo annotato espone un'operazione del servizio Web.
Il Listato 2 presenta la UCImpl
classe del servizio Web .
Listato 2. Service Implementation Bean del servizio Web UC
package ca.javajeff.uc; import javax.jws.WebService; @WebService(endpointInterface = "ca.javajeff.uc.UC") public class UCImpl implements UC { @Override public double c2f(double degrees) { return degrees * 9.0 / 5.0 + 32; } @Override public double cm2in(double cm) { return cm / 2.54; } @Override public double f2c(double degrees) { return (degrees - 32) * 5.0 / 9.0; } @Override public double in2cm(double in) { return in * 2.54; } }
UCImpl
descrive un Service Implementation Bean (SIB) , che fornisce un'implementazione della SEI. Questa classe viene dichiarata come SIB tramite l' @WebService(endpointInterface = "ca.javajeff.uc.UC")
annotazione. L' endpointInterface
elemento collega questo SIB al suo SEI ed è necessario per evitare errori di tipo di porta non definiti durante l'esecuzione dell'applicazione client presentata in seguito.
La implements UC
clausola non è assolutamente necessaria. Se questa clausola non è presente, l' UC
interfaccia viene ignorata (ed è ridondante). Tuttavia, è una buona idea mantenere in implements UC
modo che il compilatore possa verificare che i metodi SEI siano stati implementati nel SIB.
Le intestazioni del metodo del SIB non sono annotate @WebMethod
perché questa annotazione viene tipicamente utilizzata nel contesto della SEI. Tuttavia, se si dovesse aggiungere un public
metodo (conforme alle regole nella sezione 5 della specifica JAX-RPC 1.1) al SIB e se questo metodo non espone un'operazione del servizio Web, si annoterà l'intestazione del metodo @WebMethod(exclude = true)
. Assegnando true
a @WebMethod
's exclude
elemento, si impedisce che il metodo di essere associato con un'operazione.
Questo servizio Web è pronto per essere pubblicato in modo che sia possibile accedervi dai client. Il listato 3 presenta UCPublisher
un'applicazione che esegue questa attività nel contesto del server HTTP leggero predefinito.
Listato 3. Pubblicazione di UC
import javax.xml.ws.Endpoint; import ca.javajeff.uc.UCImpl; public class UCPublisher { public static void main(String[] args) { Endpoint.publish("//localhost:9901/UC", new UCImpl()); } }
La pubblicazione del servizio Web implica l'esecuzione di una singola chiamata al metodo della EndPoint
classe della Endpoint publish(String address, Object implementor)
classe. Il address
parametro identifica l'URI assegnato al servizio Web. Ho scelto di pubblicare questo servizio Web sull'host locale specificando localhost
(equivalente all'indirizzo IP 127.0.0.1) e il numero di porta 9901
(che è molto probabilmente disponibile). Inoltre, ho scelto arbitrariamente /UC
come percorso di pubblicazione. Il implementor
parametro identifica un'istanza di UC
SIB.
Il publish()
metodo crea e pubblica un endpoint per l' implementor
oggetto specificato nel dato address
e utilizza le implementor
annotazioni di per creare documenti WSDL (Web Services Definition Language) e XML Schema. Fa sì che l'infrastruttura server necessaria venga creata e configurata dall'implementazione JAX-WS in base a una configurazione predefinita. Inoltre, questo metodo fa sì che l'applicazione venga eseguita a tempo indeterminato. (Su macchine Windows, premere contemporaneamente i tasti Ctrl e C per terminare l'applicazione.)
Creazione e verifica del servizio web
Non è difficile creare il servizio Web UC definito in precedenza. Innanzitutto, è necessario creare una struttura di directory adatta contenente i file appropriati. Completa questa attività eseguendo i seguenti passaggi:
- All'interno della directory corrente, crea una
ca
directory. All'internoca
, crea unajavajeff
directory. Infine, all'internojavajeff
, crea unauc
directory. - Copia il listato 1 in un
UC.java
file sorgente e archivia questo file in formatoca/javajeff/uc
. - Copia il listato 2 in un
UCImpl.java
file sorgente e archivia questo file in formatoca/javajeff/uc
. - Copiare il listato 3 in un
UCPublisher.java
file sorgente e archiviare questo file nella directory corrente, che contiene laca
directory.
Il prossimo compito è compilare questi file di origine. Supponendo che tu non abbia cambiato directory, esegui il seguente comando per compilare questi file sorgente in Java SE 9 (ometti --add-modules java.xml.ws
in Java SE 6, 7 o 8):
javac --add-modules java.xml.ws UCPublisher.java
Se questi file sorgente vengono compilati correttamente, eseguire il comando seguente per eseguire questa applicazione in Java 9 (omettere --add-modules java.xml.ws
in Java SE 6, 7 o 8):
java --add-modules java.xml.ws UCPublisher
Durante l'esecuzione dell'applicazione, utilizzare un browser Web per verificare che questo servizio Web sia in esecuzione correttamente e per accedere al relativo documento WSDL. Avvia il tuo browser Web preferito e inserisci la seguente riga nella barra degli indirizzi:
//localhost:9901/UC
La figura 1 mostra la pagina Web risultante nel browser Web Google Chrome.
Figura 1. La pagina Web di UC fornisce informazioni dettagliate sul servizio Web pubblicato
La figura 1 presenta il servizio qualificato dell'endpoint del servizio Web e i nomi delle porte. (Notare che il nome del pacchetto è stato invertito - uc.javajeff.ca
invece di ca.javajeff.uc
). Un client utilizza questi nomi per accedere al servizio.
La Figura 1 presenta anche l'URI dell'indirizzo del servizio Web, la posizione del documento WSDL del servizio Web (l'URI del servizio Web con suffisso della ?wsdl
stringa di query) e il nome qualificato dal pacchetto della classe di implementazione del servizio Web.
Interpretazione del documento WSDL del servizio web
La posizione del documento WSDL del servizio Web UC viene presentata come collegamento. Fare clic su questo collegamento per visualizzare il documento WSDL, i cui contenuti sono presentati nel Listato 4.
Listato 4. Documento WSDL di UC
Un documento WSDL è un documento XML con un definitions
elemento radice, che rende un documento WSDL nient'altro che un insieme di definizioni. Questo elemento include vari xmlns
attributi per identificare vari spazi dei nomi standard, insieme a attributi targetNameSpace
e name
:
- L'
targetNamespace
attributo crea uno spazio dei nomi per tutti gli elementi definiti dall'utente nel documento WSDL (come l'c2f
elemento definito tramite l'message
elemento con questo nome). Questo spazio dei nomi viene utilizzato per distinguere tra gli elementi definiti dall'utente del documento WSDL corrente e gli elementi definiti dall'utente dei documenti WSDL importati, che vengono identificati tramite l'import
elemento WSDL . In modo simile, l'targetNamespace
attributo che appare sull'elemento di un file basato su XML Schemaschema
crea uno spazio dei nomi per i suoi elementi di tipo semplice definiti dall'utente, elementi di attributo e elementi di tipo complesso. - L'
name
attributo identifica il servizio Web e viene utilizzato solo per documentare il servizio.
Nidificato all'interno definitions
sono types
, message
, portType
, binding
, e service
gli elementi: