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' UCinterfaccia 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); }

UCdescrive 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.

UCviene dichiarato SEI tramite l' @WebServiceannotazione. Quando viene annotata un'interfaccia o una classe Java @WebService, tutti i publicmetodi 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 publici metodi possono essere dichiarati nelle interfacce, la publicparola riservata non è necessario quando si dichiara c2f(), cm2in(), f2c(), e in2cm(). Questi metodi sono implicitamente public.

Ogni metodo è anche annotato @WebMethod. Sebbene @WebMethodnon 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 UCImplclasse 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; } }

UCImpldescrive 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' endpointInterfaceelemento 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 UCclausola non è assolutamente necessaria. Se questa clausola non è presente, l' UCinterfaccia viene ignorata (ed è ridondante). Tuttavia, è una buona idea mantenere in implements UCmodo che il compilatore possa verificare che i metodi SEI siano stati implementati nel SIB.

Le intestazioni del metodo del SIB non sono annotate @WebMethodperché questa annotazione viene tipicamente utilizzata nel contesto della SEI. Tuttavia, se si dovesse aggiungere un publicmetodo (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 truea @WebMethod's excludeelemento, 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 UCPublisherun'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 EndPointclasse della Endpoint publish(String address, Object implementor)classe. Il addressparametro 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 /UCcome percorso di pubblicazione. Il implementorparametro identifica un'istanza di UCSIB.

Il publish()metodo crea e pubblica un endpoint per l' implementoroggetto specificato nel dato addresse utilizza le implementorannotazioni 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:

  1. All'interno della directory corrente, crea una cadirectory. All'interno ca, crea una javajeffdirectory. Infine, all'interno javajeff, crea una ucdirectory.
  2. Copia il listato 1 in un UC.javafile sorgente e archivia questo file in formato ca/javajeff/uc.
  3. Copia il listato 2 in un UCImpl.javafile sorgente e archivia questo file in formato ca/javajeff/uc.
  4. Copiare il listato 3 in un UCPublisher.javafile sorgente e archiviare questo file nella directory corrente, che contiene la cadirectory.

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.wsin 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.wsin 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.cainvece 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 ?wsdlstringa 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 definitionselemento radice, che rende un documento WSDL nient'altro che un insieme di definizioni. Questo elemento include vari xmlnsattributi per identificare vari spazi dei nomi standard, insieme a attributi targetNameSpacee name:

  • L' targetNamespaceattributo crea uno spazio dei nomi per tutti gli elementi definiti dall'utente nel documento WSDL (come l' c2felemento definito tramite l' messageelemento 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' importelemento WSDL . In modo simile, l' targetNamespaceattributo che appare sull'elemento di un file basato su XML Schema schemacrea uno spazio dei nomi per i suoi elementi di tipo semplice definiti dall'utente, elementi di attributo e elementi di tipo complesso.
  • L' nameattributo identifica il servizio Web e viene utilizzato solo per documentare il servizio.

Nidificato all'interno definitionssono types, message, portType, binding, e servicegli elementi: