Web Services to zbiór technologii pozwalających na udostępnianie usług w sieci WWW.
zdefiniowana przez kosorcjum W3C (www.w3.org/2002/ws)
jest połączeniem kilku istniejących wcześniej technologii
niezależne od platformy – może łączyć różne środowiska
działa na zasadzie komunikatów
opiera się na standardowych protokołach komunikacyjnych (HTTP, XML)
wraz z usługą udostępniana jest sformalizowana specyfikacja interfejsu programistycznego Na jej podstawie użytkownicy są w stanie łatwo stworzyæ oprogramowanie korzystające z danej uslugi.
podjęto próby stworzenia katalogow uslug publicznych dostepnych w internecie n.p. (UDDI)
CORBA
RMI
DCOM
zdeiniowane za pomoca jezyka WSDL (Web Services Description Language). (definicja WSDL może być w szczególności umieszczona w sieci WWW)
komunikaty przekazywane są w formacie XML-RPC albo SOAP
komunikaty są przekazywane za pomocą protokołu HTTP
informacja o usłudze może być umieszczona w publicznym katalogu usług (np. UDDI)
Natywnie:
J2EE
.NET
Borland Delphi / C++ Builder
Dodatkowe biblioteki:
Java (JAX-RPC i JAX-WS)
Java (Axis)
Python (http://pywebsvcs.sourceforge.net)
PHP
C/C++
i wiele innych
Szyfrowanie realizowane przez warstwę transportową (HTTPS)
Możemy filtrować pakiety HTTP na firewallu na podstawie nagłówków
Rozszerzenia implementujące autoryzację (WS-Security)
W Javie usługi sieciowe są poprostu klasami. Korzystanie z usługi polega na zdalnym wywoływaniu metod udostępnionych klas – analogicznie do RMI.
Klasa implementująca usługę sieciową:
Musi implementować interfejs java.rmi.remote
Nie może mieć deklaracji stałych
Wszystkie metody muszą wyrzucać wyjątki java.rmi.RemoteException
Parametry metod i zwracane wyniki muszą być określonych typów (o tym niżej)
Warto stworzyć oddzielny interfejs dla tej klasy – wówczas wszystkie pliki pomocnicze zostaną wygenerowane w oparciu o interfejs a my będziemy mogli w ramach tego interfejsu tworzyć dowolne implementacje.
Prymitywy (boolean, byte, double, float, int, logn, short)
Typy opakowujące prymitywy
Obiekty klas java.math.BigDecimal, java.math.BigInteger, java.net.URI, java.util.Calendar, java.util.Date
Tablice
Klasy zdefiniowane przez użytkownika spełniające poniższe warunki
Bezparametrowy konstruktor
NIE implementują interfejsu java.rmi.remote
Wszystkie pola są publiczne albo mają gettery i settery
Pola muszą być typów obsługiwanych przez JAX-RPC
Klient tworzy klasę proxy odpowiadającą danej usłudze. Klasa proxy tłumaczy wywołania metod na komunikaty SOAP
Komunikat SOAP jest wysyłany do serwera usługi
Serwer usługi tłumaczy komunikat SOAP na wywołanie metody odpowiedniej klasy
Serwer wywołuje metodę
Serwer pakuje wynik działania metody do pakietu SOAP
Komunikat SOAP jest wysyłany do klienta
Klasa proxy klienta tłumaczy komunikat na właściwy rezultat
Zwykle HTTP, ale w ogólności każdy protokół potrafiący pracowaæ na zasadzie zapytanie/odpowiedź.
Dwa podstawowe formaty komunikatów stosowane w webserwisach to XML-RPC i SOAP. Oba oparte są na XML'u. Poniżej krótki opis każdego z nich.
Protokol XML pierwszej generacji. bazuje na mechaniźmie RPC. Wywołanie zdalnej metody polega na wysłaniu komunikatu o formacie jak poniżej:
<?xml version="1.0"?> <methodCall> <methodName>examples.getStateName</methodName> <params> <param> <value><i4>41</i4></value> </param> </params> </methodCall>
Usługa wysyła nam odpowieddź w następującym formacie:
<?xml version="1.0"?> <methodResponse> <params> <param> <value><string>South Dakota</string></value> </param> </params> </methodResponse>
Protokół XML drugiej generacji zdefiniowany przez konsorcjum W3C. Może służyć do przekazywania obiektów i wywołań metod. Nas interesowaæ będzie zdalne wywoływanie metod. Komunikat SOAP składa się z koperty w której umieszczony jest nagłówek i ciało komunikatu. Nagłówek zawiera informacje o środowisku wykonania metody, n.p. identyfikator transakcji. W ciele komunikatu znajduje się informacja o właściwym wywołaniu metody - nazwa metody i argumenty. Poniżej przykładowe wywołanie metody:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <echo SOAP-ENC:root="1"> <_1 xsi:type="xsd:string">Hello world</_1> </echo> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Oraz odpowiedź na powyższe wywołanie:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <echoResponse SOAP-ENC:root="1"> <Result xsi:type="xsd:string">Hello worldHello world</Result> </echoResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Nieodłączną częścią webserwisu jest sformalizowana specyfikacja pozwalająca na łatwe stworzenie interfejsu programistycznego do usługi. Standard Web Services przewiduje formalną specyfikację interfejsów w postaci dokumentów w formacie WSDL (Web Services Definition Language). Jest wiele narzędzi generujących kod dokumentów WSDL klasy łączące się z usługą.
Format WSDL został zaprojektowany przez firmy IBM i Microsoft. Jest oparty na XML'u. Dokument WSDL zawiera informację o położeniu WebSerwisu, udostępnionych metodach oraz szczegółach używanych protokołów (n.p. czy używamy XML-RPC czy SOAP). Poniżej przykład.
<?xml version="1.0"?> <definitions name="StockQuote" targetNamespace="http://example.com/stockquote.wsdl" xmlns:tns="http://example.com/stockquote.wsdl" xmlns:xsd1="http://example.com/stockquote.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema targetNamespace="http://example.com/stockquote.xsd" xmlns="http://www.w3.org/2000/10/XMLSchema"> <element name="TradePriceRequest"> <complexType> <all> <element name="tickerSymbol" type="string"/> </all> </complexType> </element> <element name="TradePrice"> <complexType> <all> <element name="price" type="float"/> </all> </complexType> </element> </schema> </types> <message name="GetLastTradePriceInput"> <part name="body" element="xsd1:TradePriceRequest"/> </message> <message name="GetLastTradePriceOutput"> <part name="body" element="xsd1:TradePrice"/> </message> <portType name="StockQuotePortType"> <operation name="GetLastTradePrice"> <input message="tns:GetLastTradePriceInput"/> <output message="tns:GetLastTradePriceOutput"/> </operation> </portType> <binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetLastTradePrice"> <soap:operation soapAction="http://example.com/GetLastTradePrice"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="StockQuoteService"> <documentation>My first service</documentation> <port name="StockQuotePort" binding="tns:StockQuoteSoapBinding"> <soap:address location="http://example.com/stockquote"/> </port> </service> </definitions>
JAX-RPC (Java API for XML-based Remote Procedure Call)
JAX-WS (Java API fir XML-based Web Services) – następca JAX-RPC, zmienione biblioteki, oparty na anotacjach, ma być dołączany standardowo do javy 1.6
Opensourcowa implementacja standardów JAX-RPC i JAX-WS tworzona w ramach projektu GlassFish. Standardowo dołączana do serwerów aplikacji Suna
Opensourceowa implementacja protokołu SOAP, rozwinięcie wcześniejszego projektu Apache SOAP. Dostępna dla Javy i C++. Oparta na API JAX-RPC.
Począwszy od standardu J2EE 1.4 każdy serwer aplikacji J2EE musi posiadaæ wbudowaną implementację web serwisów. Dodatkowo serwery aplikacji powinny umożliwiać udostępnianie w sieci komponentów EJB. JBoss posiada taką funkcjonalność.
JBoss zawiera pełną implementację API Web Services. Przygotowanie web serwisu składa się z następujścych czynności.
Stworzenie interfejsu naszego Web Serwisu
Stworzenie implementacji web serwisu realizującej interfejs
Wygenerowanie plików WSDL i mappingu typów SOAP na typy Javy. (o narzędziach pomocniczych w kolejnej części)
Stworzenie pliku web.xml opisującego komponenty WWW
Stworzenie pliku webservices.xml opisującego udostępnione webserwisy
Stworzenie pakietu WAR z webserwisem
JBoss udostępnia nam wszystkie biblioteki potrzebne do skorzystania z web services, jednak aby do kompilacji programu klienckiego będziemy potrzebowali z plików znajdujących się w katalogu
jax_rpc/przyklady/lib
Zwykle chcemy skorzystaæ z usługi której interfejs
znamy. Mechanizm JAX-RPC potrafi stworzyć automatycznie klasę proxy
która będzie łaczyć się z usługą i realizować wskazany przez
nas interfejs. Po pobraniu klasy proxy możemy się nią posługiwać tak
jak każdą zwykłą klasą Javy.
Przykład klienta korzystającego z
klasy proxy znajduje się w pliku:
jax_rpc/przyklady/klient/KlientJBoss.java
Jest to serwlet który jest dostępny pod adresem:
http://127.0.0.1:8080/WS/KlientJBOSS
Czasem zdarza się że chcemy skorzystaæ z usługi, której nie znamy dokładnie na etapie tworzenia aplikacji. Mechanizm DII (Direct Interface Invocation) pozwala nam na wywoływanie metod usług sieciowych w oparciu o dynamicznie ustalane nazy (w postaci Stringa) i parametry (w formie tablicy obiektów). Przykład klienta korzystającego z mechanizmu DII znajduje się w pliku
jax_rpc/przyklady/klient/KlientDII.java
W specyfikacji J2EE5 wprowadzono nowy sposób tworzenia webserwisów pozwalający zaoszczędzić czas poświęcony na tworzenie dodatkowych plików konfiguracyjnych. W miejsce pliku webservices.xml możemy użyć odpowiednich anotacji. Proszę spojrzeć na plik jax_ws/przyklady/serwer/SerwerJWS.java. Wprowadzone są tutaj anotacje
@Webservice którymi oznaczamy klasy, które mają byæ udostêpnione
@Webmethod którymi oznaczymy metody klas, które chcemy udostępnić.
Obsługa JAX-WS pojawiła w JBossie dosyć niedawno przy okazji zmiany całego podsystemu Webserwisów (jest w wersji JBoss 4.0.4.GA).
Jeśli nie mamy do dyspozycji serwera aplikacji a chcielibyśmy skorzystaæ z dobrodziejstw jakie dają nam webserwisy, możemy skorzystaæ z biblioteki AXIS. Za jej pomocą możemy udostępniać usługi sieciowe na dowolnym serwerze serwletów, oraz korzystać z udostępnionych usług z poziomu dowolnego programu w Javie.
W kolejnym przykładzie połączymy się z istniejącą usługą sieciową za pomocą programu konsolowego. Przykład jest dostępny w pliku axis/przyklady/klient/KlientAxis.java. Uruchamiamy go poleceniem ./uruchom_przyklad z katalogu z przykładami.
Xdoclet – pozwala wygenerować pliki pomocnicze dla Axis'a
Pakiet JAX-RPC Developer pack zawierający między innymi
Pliki z klasami JAX-RPC
Narzędzie wscompile generujące pliki pomocnicze na podstawie klasy usługi sieciowej lub na podstawie pliku WSDL
Jboss w wersji 4.0.4.GA zawiera zestaw narzędzi Wstools dostępny poprzez skrypt jboss_home/bin/wstool.sh oraz jako zadanie do Anta
Axis zawiera między innymi
TCPmonitor i SOAP monitor – przydatne do analizy komunikatów SOAP
SOAP monitor
Java2WSDL, WSDL2Java – narzędzia do zamiany interfejsów Javy na WSDL i odwrotnie
Spróbujcie zmienić usługę HelloWorld dodając do niej nowe metody przyjmujące obiekty jako argumenty.
Stwórzcie własny wyjątek i spróbujcie stworzyæ metodę wyrzucającą ten wyjątek.
Przejrzyjcie wygenerowane podczas pracy pliki WSDL - zwróćcie uwagę w jaki sposób opisywane są złożone typy danych i możliwe wyjątki