Usługi sieciowe w Java SE, Część 2: Tworzenie usług sieciowych SOAP

JAX-WS obsługuje usługi sieci Web oparte na protokole SOAP. Część 2 tej czteroczęściowej serii poświęconej usługom sieciowym Java SE definiuje usługę internetową konwersji jednostek opartą na protokole SOAP, buduje, a następnie weryfikuje tę usługę sieci Web lokalnie za pośrednictwem domyślnego lekkiego serwera HTTP (omówionego w części 1), interpretuje dokument WSDL usługi i uzyskuje dostęp do usługi z poziomu prostego klienta.

Definiowanie usługi internetowej konwersji jednostek

Usługa sieciowa konwersji jednostek, którą nazwałem UC, składa się z czterech funkcji do konwersji między centymetrami i calami oraz między stopniami Fahrenheita i stopniami Celsjusza. Chociaż ten przykład można zaprojektować jako pojedynczą klasę Java, zdecydowałem się postępować zgodnie z najlepszymi praktykami, tworząc go jako interfejs Java i klasę Java. Listing 1 przedstawia UCinterfejs usługi sieciowej.

Lista 1. Interfejs punktu końcowego usługi sieci 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); }

UCopisuje interfejs punktu końcowego usługi (SEI) , który jest interfejsem Java, który ujawnia operacje interfejsu usługi sieci Web w kategoriach abstrakcyjnych metod języka Java. Klienci komunikują się z usługami sieciowymi opartymi na SOAP za pośrednictwem swoich SEI.

UCjest deklarowany jako SEI poprzez @WebServiceadnotację. Gdy interfejs lub klasa Java jest opatrzona adnotacjami @WebService, wszystkie publicmetody, których parametry, zwracane wartości i zadeklarowane wyjątki są zgodne z regułami zdefiniowanymi w sekcji 5 specyfikacji JAX-RPC 1.1, opisują operacje usługi WWW. Bo tylko publicmetody mogą być zadeklarowane w interfejsom, publiczarezerwowanym słowem nie jest konieczne podczas deklarowania c2f(), cm2in(), f2c(), i in2cm(). Te metody są niejawne public.

Każda metoda jest również opisana @WebMethod. Chociaż @WebMethodnie jest to niezbędne w tym przykładzie, jego obecność wzmacnia fakt, że metoda z adnotacjami uwidacznia operację usługi sieci Web.

Listing 2 przedstawia UCImplklasę usługi sieci Web .

Listing 2. Element bean implementacji usługi sieci 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; } }

UCImplopisuje komponent Bean Service Implementation Bean (SIB) , który zapewnia implementację SEI. Ta klasa jest zadeklarowana jako SIB za pośrednictwem @WebService(endpointInterface = "ca.javajeff.uc.UC")adnotacji. endpointInterfaceElement ten łączy SIB jego SEI, a jest to konieczne w celu uniknięcia błędów Typ portu niezdefiniowane podczas uruchamiania aplikacji klienckiej podane później.

implements UCKlauzula nie jest to absolutnie konieczne. Jeśli ta klauzula nie jest obecna, UCinterfejs jest ignorowany (i jest nadmiarowy). Warto jednak zachować implements UCto, aby kompilator mógł sprawdzić, czy metody SEI zostały zaimplementowane w SIB.

Nagłówki metody SIB nie są opatrzone adnotacjami, @WebMethodponieważ ta adnotacja jest zwykle używana w kontekście SEI. Jeśli jednak dodasz publicmetodę (która jest zgodna z regułami w sekcji 5 specyfikacji JAX-RPC 1.1) do SIB i jeśli ta metoda nie ujawnia operacji usługi sieci Web, musisz dodać adnotację do nagłówka metody @WebMethod(exclude = true). Przypisując element truedo elementu @WebMethod's exclude, zapobiegasz skojarzeniu tej metody z operacją.

Ta usługa sieci Web jest gotowa do opublikowania, aby można było uzyskać do niej dostęp z klientów. Listing 3 przedstawia UCPublisheraplikację, która wykonuje to zadanie w kontekście domyślnego lekkiego serwera HTTP.

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

Publikowanie usługi sieci Web wymaga podejmowania pojedynczy wywołanie EndPointklasa jest Endpoint publish(String address, Object implementor)metoda klasy. W addressidentyfikuje parametr URI przypisany do usługi internetowej. Zdecydowałem się opublikować tę usługę sieciową na lokalnym hoście, podając localhost(odpowiednik adresu IP 127.0.0.1) i numer portu 9901(który jest najprawdopodobniej dostępny). Poza tym arbitralnie wybrałem /UCścieżkę publikacji. W implementoridentyfikuje parametr instancję UC„s SIB.

publish()Metoda tworzy i publikuje końcowy dla określonego implementorprzedmiotu w danym address, i korzysta z implementor„s adnotacje do tworzenia stron internetowych Definition Language (WSDL) i XML Schema dokumentów. To powoduje, że niezbędna infrastruktura serwerowa jest tworzona i konfigurowana przez implementację JAX-WS w oparciu o domyślną konfigurację. Ponadto ta metoda powoduje, że aplikacja działa w nieskończoność. (Na komputerach z systemem Windows naciśnij jednocześnie klawisze Ctrl i C, aby zamknąć aplikację).

Budowa i weryfikacja usługi internetowej

Nie jest trudno zbudować wcześniej zdefiniowaną usługę internetową UC. Najpierw musisz stworzyć odpowiednią strukturę katalogów zawierającą odpowiednie pliki. Wykonaj to zadanie, wykonując następujące czynności:

  1. W bieżącym katalogu utwórz cakatalog. Wewnątrz cautwórz javajeffkatalog. Na koniec javajeffutwórz uckatalog.
  2. Skopiuj Listing 1 do UC.javapliku źródłowego i zapisz ten plik w formacie ca/javajeff/uc.
  3. Skopiuj Listing 2 do UCImpl.javapliku źródłowego i zapisz ten plik w formacie ca/javajeff/uc.
  4. Skopiuj Listing 3 do UCPublisher.javapliku źródłowego i zapisz ten plik w bieżącym katalogu, który zawiera cakatalog.

Następnym zadaniem jest skompilowanie tych plików źródłowych. Zakładając, że nie zmieniłeś katalogów, wykonaj następujące polecenie, aby skompilować te pliki źródłowe w Javie SE 9 (pomiń --add-modules java.xml.wsw Java SE 6, 7 lub 8):

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

Jeśli te pliki źródłowe skompilują się pomyślnie, wykonaj następujące polecenie, aby uruchomić tę aplikację w Javie 9 (pomiń --add-modules java.xml.wsw Java SE 6, 7 lub 8):

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

Podczas działania aplikacji użyj przeglądarki sieci Web, aby sprawdzić, czy ta usługa sieci Web działa poprawnie i uzyskać dostęp do jej dokumentu WSDL. Uruchom swoją ulubioną przeglądarkę internetową i wprowadź następujący wiersz w pasku adresu:

//localhost:9901/UC

Rysunek 1 przedstawia wynikową stronę internetową w przeglądarce internetowej Google Chrome.

Rysunek 1. Strona internetowa UC zawiera szczegółowe informacje na temat opublikowanej usługi internetowej

Rysunek 1 przedstawia kwalifikowaną usługę i nazwy portów punktu końcowego usługi sieci Web. (Zauważ, że nazwa pakietu została odwrócona - uc.javajeff.cazamiast ca.javajeff.uc). Klient używa tych nazw, aby uzyskać dostęp do usługi.

Rysunek 1 przedstawia również adres URI usługi sieci Web, lokalizację dokumentu WSDL usługi sieci Web (identyfikator URI usługi sieci Web z sufiksem ciągu ?wsdlzapytania) oraz kwalifikowaną nazwę pakietu klasy implementacji usługi sieci Web.

Interpretacja dokumentu WSDL usługi WWW

Lokalizacja dokumentu WSDL usługi UC Web Service jest prezentowana jako łącze. Kliknij to łącze, aby wyświetlić dokument WSDL, którego zawartość jest przedstawiona na listingu 4.

Listing 4. Dokument WSDL UC

Dokument WSDL to dokument XML z definitionselementem głównym, co sprawia, że ​​dokument WSDL jest niczym innym jak zestawem definicji. Ten element zawiera różne xmlnsatrybuty służące do identyfikowania różnych standardowych przestrzeni nazw, wraz z atrybutami targetNameSpacei name:

  • targetNamespaceAtrybut tworzy nazw dla wszystkich elementów zdefiniowanych przez użytkownika w dokumencie WSDL (takich jak c2felementu zdefiniowanego przez messageelementu o tej nazwie). Ta przestrzeń nazw jest używana do rozróżniania między elementami zdefiniowanymi przez użytkownika bieżącego dokumentu WSDL a elementami zdefiniowanymi przez użytkownika w importowanych dokumentach WSDL, które są identyfikowane za pomocą importelementu WSDL . W podobny sposób targetNamespaceatrybut, który pojawia się w schemaelemencie pliku opartego na schemacie XML, tworzy przestrzeń nazw dla elementów typu prostego zdefiniowanego przez użytkownika, elementów atrybutu i elementów typu złożonego.
  • nameAtrybut identyfikuje usługę internetową i jest używany tylko w celu udokumentowania usługi.

Zagnieżdżone definitionstypes, message, portType, binding, i serviceelementów: