Webbtjänster i Java SE, del 2: Skapa SOAP-webbtjänster

JAX-WS stöder SOAP-baserade webbtjänster. Del 2 i denna fyrdelarserie på Java SE-webbtjänster definierar en SOAP-baserad enhetskonvertering webbtjänst, bygger och verifierar sedan denna webbtjänst lokalt via standardlättvikts HTTP-server (diskuteras i del 1), tolkar tjänstens WSDL-dokument och får åtkomst till tjänsten från en enkel klient.

Definiera en webbtjänst för omvandling av enheter

Enhetens omvandling webbtjänst, som jag har kallat UC, består av fyra funktioner för att konvertera mellan centimeter och tum och mellan grader Fahrenheit och grader Celsius. Även om detta exempel skulle kunna arkiveras som en enda Java-klass har jag valt att följa bästa praxis genom att arkivera det som ett Java-gränssnitt och en Java-klass. Listning 1 visar webbtjänstens UCgränssnitt.

Listning 1. UC-webbtjänstens Service Endpoint Interface

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

UCbeskriver ett Service Endpoint Interface (SEI) , vilket är ett Java-gränssnitt som exponerar ett webbtjänstgränssnitts operationer i termer av abstrakta Java-metoder. Kunder kommunicerar med SOAP-baserade webbtjänster via sina SEI.

UCförklaras vara ett SEI via @WebServiceanteckningen. När ett Java-gränssnitt eller en klass antecknas följer @WebServicealla publicmetoder vars parametrar, returvärden och deklarerade undantag reglerna som definieras i avsnitt 5 i JAX-RPC 1.1-specifikationen webbtjänståtgärder. Eftersom endast publicmetoder kan deklareras i gränssnitt, det publicär reserverat ord inte nödvändigt när förklara c2f(), cm2in(), f2c(), och in2cm(). Dessa metoder är implicit public.

Varje metod antecknas också @WebMethod. Även om det @WebMethodinte är nödvändigt i detta exempel, förstärker dess närvaro det faktum att den kommenterade metoden exponerar en webbtjänst.

Listning 2 presenterar webbtjänstens UCImplklass.

Listing 2. UC-webbtjänstens Service Implementation Bean

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; } }

UCImplbeskriver en Service Implementation Bean (SIB) , som ger en implementering av SEI. Denna klass förklaras vara en SIB via @WebService(endpointInterface = "ca.javajeff.uc.UC")anteckningen. Den endpointInterfacedel förbinder detta SIB till sin SEI, och är nödvändigt för att undvika odefinierade typ port fel när du kör programmet klienten presenteras senare.

Den implements UCklausulen är inte absolut nödvändigt. Om denna klausul inte finns UCignoreras gränssnittet (och är överflödigt). Det är dock en bra idé att behålla implements UCså att kompilatorn kan verifiera att SEI: s metoder har implementerats i SIB.

SIB: s metodrubriker är inte antecknade @WebMethodeftersom den här anteckningen vanligtvis används i SEI-sammanhanget. Men om du skulle lägga till en publicmetod (som överensstämmer med reglerna i avsnitt 5 i JAX-RPC 1.1-specifikationen) till SIB, och om den här metoden inte exponerar en webbtjänstoperation, skulle du kommentera metodhuvudet @WebMethod(exclude = true). Genom att tilldela truetill @WebMethod's excludeelement, hindra dig denna metod från att associeras med en operation.

Denna webbtjänst är redo att publiceras så att den kan nås från klienter. Listning 3 presenterar en UCPublisherapplikation som utför denna uppgift i samband med standardlättvikts HTTP-servern.

Listing 3. Publicering 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()); } }

Att publicera webbtjänsten innebär att ringa ett enda samtal till EndPointklassens Endpoint publish(String address, Object implementor)klassmetod. De addressparameter identifierar URI tilldelats webbtjänst. Jag har valt att publicera den här webbtjänsten på den lokala värden genom att ange localhost(motsvarar IP-adress 127.0.0.1) och portnummer 9901(vilket sannolikt är tillgängligt). Jag har också godtyckligt valt /UCsom publiceringsväg. De implementorparameter konstateras ett fall av UCs SIB.

Den publish()metod skapar och publicerar en slutpunkt för det angivna implementorobjektet i den givna addressoch använder implementor's anteckningar för att skapa Web Services Definition Language (WSDL) och XML Schema-dokument. Det gör att den nödvändiga serverinfrastrukturen skapas och konfigureras av JAX-WS-implementeringen baserat på någon standardkonfiguration. Dessutom gör denna metod att applikationen körs på obestämd tid. (På Windows-maskiner trycker du samtidigt på Ctrl och C för att avsluta applikationen.)

Bygga och verifiera webbtjänsten

Det är inte svårt att bygga den tidigare definierade UC-webbtjänsten. Först måste du skapa en lämplig katalogstruktur som innehåller lämpliga filer. Utför denna uppgift genom att utföra följande steg:

  1. Skapa en katalog i den aktuella cakatalogen. Inom ca, skapa en javajeffkatalog. Slutligen, inom javajeff, skapa en uckatalog.
  2. Kopiera Listing 1 till en UC.javakällfil och lagra den här filen i ca/javajeff/uc.
  3. Kopiera Listing 2 till en UCImpl.javakällfil och lagra den här filen i ca/javajeff/uc.
  4. Kopiera Listing 3 till en UCPublisher.javakällfil och lagra den här filen i den aktuella katalogen, som innehåller cakatalogen.

Nästa uppgift är att kompilera dessa källfiler. Antag att du inte har bytt katalog, kör följande kommando för att kompilera dessa källfiler i Java SE 9 (utelämna --add-modules java.xml.wsi Java SE 6, 7 eller 8):

javac --add-modules java.xml.ws UCPublisher.java

Om dessa källfiler kompileras framgångsrikt kör du följande kommando för att köra det här programmet i Java 9 (utelämna --add-modules java.xml.wsi Java SE 6, 7 eller 8):

java --add-modules java.xml.ws UCPublisher

Medan applikationen körs, använd en webbläsare för att verifiera att den här webbtjänsten fungerar korrekt och för att få åtkomst till WSDL-dokumentet. Starta din favoritwebbläsare och ange följande rad i adressfältet:

//localhost:9901/UC

Figur 1 visar den resulterande webbsidan i webbläsaren Google Chrome.

Figur 1. UC: s webbsida ger detaljerad information om den publicerade webbtjänsten

Figur 1 visar webbtjänstens slutpunkts kvalificerade service- och portnamn. (Observera att paketnamnet har inverterats - uc.javajeff.caistället för ca.javajeff.uc). En klient använder dessa namn för att komma åt tjänsten.

Figur 1 visar också adressen URI för webbtjänsten, platsen för webbtjänstens WSDL-dokument (webbtjänstens URI efterfrågad av ?wsdlfrågesträngen) och det paketkvalificerade namnet på implementeringsklassen för webbtjänsten.

Tolkar webbtjänstens WSDL-dokument

Platsen för UC-webbtjänstens WSDL-dokument presenteras som en länk. Klicka på den här länken för att se WSDL-dokumentet, vars innehåll presenteras i Listing 4.

Listning 4. UC: s WSDL-dokument

Ett WSDL-dokument är ett XML-dokument med ett definitionsrotelement, vilket gör ett WSDL-dokument inte mer än en uppsättning definitioner. Detta element innehåller olika xmlnsattribut för att identifiera olika standardnamnområden, tillsammans med targetNameSpaceoch nameattribut:

  • The targetNamespace attribute creates a namespace for all user-defined elements in the WSDL document (such as the c2f element defined via the message element with this name). This namespace is used to distinguish between the user-defined elements of the current WSDL document and user-defined elements of imported WSDL documents, which are identified via WSDL's import element. In a similar fashion, the targetNamespace attribute that appears on an XML Schema-based file's schema element creates a namespace for its user-defined simple type elements, attribute elements, and complex type elements.
  • The name attribute identifies the Web service and is used only to document the service.

Nested within definitions are types, message, portType, binding, and service elements: