public interface TravelAgent { public void makereservation(int cruiseid, int cabinid, int customerid, double price); }

Wielkość: px
Rozpocząć pokaz od strony:

Download "public interface TravelAgent { public void makereservation(int cruiseid, int cabinid, int customerid, double price); }"

Transkrypt

1 Web Services 1. Podstawy usług sieciowych. SOAP, WSDL. 2. Usługi sieciowe w JAX-RPC. interfejs punktu końcowego, korzystanie z usługi z poziomu komponentu EJB, programy klienckie, narzędzia i deskryptory XML. 3. Usługi sieciowe w JAX-WS. adnotacje, korzystanie z usługi. 1

2 SOAP Przykładowy interfejs: public interface TravelAgent { public void makereservation(int cruiseid, int cabinid, int customerid, double price); Wywołanie metody poprzez SOAP: <env:envelope xmlns:env=" xmlns:titan=" <env:body> <titan:makereservation> <cruiseid>23</cruiseid> <cabinid>144</cabinid> <customerid>9393</customerid> <price> </price> </titan:makereservation> </env:body> </env:envelope> 2

3 WSDL Aby udostępnić usług ę poprzez sieć jako tzw. WebService należy przygotować jej opis w języku WSDL (WebService Description Language). Na jego podstawie klienci korzystający z usługi wiedz ą w jaki sposób przesyłać i interpretować odebrane dane. Umożliwia to automatyzacj ę procesu przesyłu danych i pozwala programiście skoncentrować si ę na logice aplikacji. 3

4 WSDL opis usługi WSDL służy do informowania klienta o dostępnych usługach sieciowych: <?xml version="1.0"?> <definitions name="travelagent" xmlns=" xmlns:soap=" xmlns:xsd=" xmlns:titan=" targetnamespace=" <!-- message: opis parametrów wywołania i wyników --> <message name="requestmessage"> <part name="cruiseid" type="xsd:int" /> <part name="cabinid" type="xsd:int" /> <part name="customerid" type="xsd:int" /> <part name="price" type="xsd:double" /> </message> <message name="responsemessage"> <part name="reservationid" type="xsd:string" /> </message> 4

5 WSDL opis usługi <!-- porttype opisuje interfejs usługi sieciowej --> <porttype name="travelagent"> <operation name="makereservation"> <input message="titan:requestmessage"/> <output message="titan:responsemessage"/> </operation> </porttype> Element <porttype> opisuje dostępne operacje (metody Javy). Operacja posiada wejś cie <input> i wyjś cie <output> oraz informacje o błędach (dowoln ą liczb ę ) <fault>. EJB 3.0 wspiera dwa typy usług sieciowych: request-response pojedynczy element <input> i <output> oraz ew. <fault>, one-way - wyłą cznie <input>. 5

6 WSDL opis usługi <!-- binding informuje o protokole i kodowaniu --> <binding name="travelagentbinding" type="titan:travelagent"> <soap:binding style="rpc" transport=" <operation name="makereservation"> <soap:operation soapaction="" /> <input> <soap:body use="literal" namespace=" </input> <output> <soap:body use="literal" namespace=" </output> </operation> </binding> Usługa będzie dostępna poprzez protokół SOAP. 6

7 WSDL opis usługi <!-- service: adres usługi --> <service name="travelagentservice"> <port name="travelagentport" binding="titan:travelagentbinding"> <soap:address location=" </port> </service> </definitions> Na zakończenie określamy adres pod którym usługa będzie widoczna w sieci internet. 7

8 Dostęp do WebServices poprzez JAX-RPC JAX-RPC umożliwia dostęp do usług sieciowych opartych na dowolnych platformach sprzętowych i programowych. program kliencki 1 2 pośrednik 4 3 Web Service Pośrednik (proxy) może być generowany dynamicznie na podstawie pobranej z serwera specyfikacji usługi zapisanej w języku WSDL. Do utworzenia tzw. interfejsu punktu końcowego ( endpoint interface) wykorzystuje si ę dane zawarte w elemencie porttype. 8

9 Interfejs punktu końcowego <message name="chargerequest"> <part name="name" type="xsd:string"/> <part name="number" type="xsd:string"/> <part name="exp-date" type="xsd:datetime"/> <part name="card-type" type="xsd:string"/> <part name="amount" type="xsd:float"/> </message> <message name="chargeresponse"> <part name="return" type="xsd:int"/> </message> <porttype name="processor"> <operation name="charge"> <input message="tns:chargerequest"/> <output message="tns:chargeresponse"/> </operation> </porttype> package com.charge_it; public interface Processor extends java.rmi.remote{ public int charge(string name, String number, java.util.calendar expdate, String cardtype, float amount) throws java.rmi.remoteexception; 9

10 Adres usługi <service name="processorservice"> <port name="processorport" binding="tns:processorsoapbinding"> <soap:address location=" </port> </service> Adres usługi jest podany w elemencie service. Element bingings zawiera specyfikacje odnośnie wykorzystywanego protokołu. <binding name="processorsoapbinding" type="tns:processor"> <soap:binding style="rpc" transport=" <operation name="charge"> <soap:operation soapaction="" style="rpc"/> <input><soap:body use="literal" namespace=" </input> <output><soap:body use="literal" namespace=" </output> </operation> </binding> 10

11 Adres usługi Oprócz interfejsu końcowego, w oparciu o element jest interfejs usługi: service tworzony package com.charge_it; public interface ProcessorService extends javax.xml.rpc.service{ public Processor getprocessorport() throws javax.xml.rpc.serviceexception; public Processor getprocessorport(url portaddress) throws javax.xml.rpc.serviceexception; public String getprocessorportaddress( ); Interfejs usługi pozwala na utworzenie pośrednika (Processor), poprzez którego otrzymamy dostęp do usługi sieciowej. 11

12 @Stateful public class AnyBean implements AnyRemote { private ProcessorService service; public void amethod() throws EJBException{ try{ Processor processor = service.getprocessorport(); processor.charge(customername, card.number, expdate, card.type, price); catch(exception e) { throw new EJBException(e); UWAGA: wystąpienie błędu (zwrócenie wyjątku) spowoduje anulowanie operacji wykonanych przez komponent w ramach transakcji, jednak nie spowoduje odwołania zmian wykonanych przez usług ę sieciow ą. Korzystanie z usługi sieciowej w obrębie EJB 12

13 Korzystanie z usługi sieciowej w obrębie EJB Parametry wstrzyknięcia określamy w deskryptorze wdrożenia ejbjar.xml: <ejb-name>anybean</ejb-name> <service-ref> <service-ref-name>service/processorservice</service-ref-name> <service-interface>com.charge_it.processorservice </service-interface> <wsdl-file>meta-inf/wsdl/chargeitprocessor.wsdl</wsdl-file> <jaxrpc-mapping-file>meta-inf/mapping.xml</jaxrpc-mapping-file> <service-qname>chargeit:processorservice</service-qname> <mapped-name>webservices/processorservice</mapped-name> <injection-target> <injection-target-class>anybean</injection-target-class> <injection-target-name>service</injection-target-name> </injection-target> </service-ref> 13

14 Korzystanie z usługi sieciowej w obrębie EJB Specyfikacja JAX-RPC wymaga dostarczenia odwzorowania, które wiąże WSDL i Jav ę. Zwykle jest ono umieszczone w pliku jaxrpcmapping.xml. Ponadto, w zależności od tego czy jesteśmy dostawc ą czy odbiorc ą usługi mog ą specyfikacja wymaga dodatkowych plików opisujących usług ę. Zwykle jednak producenci kontenerów EJB dostarczaj ą narzędzi, które automatycznie generuj ą wszystkie potrzebne pliki na podstawie interfejsu w Javie i kilku dodatkowych parametrów. 14

15 Korzystanie z usługi w programie klienckim public class Client { public static void main(string [] args) { try{ Context jndicontext = new javax.naming.initialcontext(); ProcessorService service = (ProcessorService)jndiContext. lookup("java:comp/env/service/processorservice"); Processor processor = service.gettravelagentport(); processor.charge(customername, card.number, expdate, card.type, price); catch (javax.naming.namingexception ne){ ne.printstacktrace(); catch (java.rmi.remoteexception re){ re.printstacktrace(); catch (javax.xml.rpc.serviceexception se){ se.printstacktrace(); 15

16 Narzędzia Producenci kontenerów EJB dostarczaj ą narzędzi pozwalających automatycznie generować potrzebne pliki. Przykład zadania Ant'a (JBoss): <target name="wstool"> <taskdef name="wstools" classname="org.jboss.ws.tools.ant.wstools"> <classpath refid="build.classpath" /> </taskdef> <wstools dest="dd/ws" config="wstools-config.xml"/> </target> oraz plik konfiguracyjny: <configuration xmlns=" <java-wsdl> <service name="processorservice" style="rpc" endpoint="com.charge_it.processorservice"/> <namespaces target-namespace=" type-namespace=" <mapping file="jaxrpc-mapping.xml"/> <webservices ejb-link="processorbean"/> </java-wsdl> </configuration> 16

17 Narzędzia Przedstawiony kod generuje następujące pliki: ProcessorService.wsdl: definicja usługi w formacie WDSL. Niektóre dane mog ą być uzupełnione po uruchomieniu usługi (np. adres SOAP). jaxrpc-mapping.xml: odwzorowanie pomiędzy typami WSDL i Javy. Może być wykorzystywany przez usług ę i klienta. webservices.xml: deklaracja usługi. Ustaniawia połączenie pomiędzy adresem usługi a komponentem EJB, który j ą realizuje. 17

18 JAX-RPC podsumowanie Usługa: interfejs punktu końcowego rozszerzający java.rmi.remote, bezstanowy komponent sesyjny implementujący interfejs punktu końcowego, deskryptory: opis usługi w WSDL'u, jaxrpc-mapping.xml, webservices.xml. Klient: interfejs usługi i interfejs punktu końcowego, odwzorowanie danych: jaxrpc-mapping.xml. 18

19 JAX-WS Aby zdefiniować usług ę sieciow ą w oparciu o bezstanowy komponent sesyjny zgodnie ze specyfikacj ą JAX-RPC należy wykonać sporo dodatkowej pracy związanej z przygotowaniem wymaganych plików opisujących usług ę. Aby zredukować t ą dodatkow ą prac ę do minimum powstała alternatywna specyfikacja JAX-WS zgodna z EJB

20 JAX-WS Aby zdefiniować usług ę sieciow ą w oparciu o bezstanowy komponent sesyjny zgodnie ze specyfikacj ą JAX-RPC należy wykonać sporo dodatkowej pracy związanej z przygotowaniem wymaganych plików opisujących usług ę. Aby zredukować t ą dodatkow ą prac ę do minimum powstała alternatywna specyfikacja JAX-WS zgodna z EJB 3.0: import javax.ejb.stateless; import javax.jws.webservice; public class public String makereservation(int cruiseid, int cabinid, int customerid, double price) { 20

21 WebService { String name( ) default ""; // nazwa usługi: wsdl:porttype, // domyślnie nazwa klasy lub // interfejsu String targetnamespace( ) default ""; // domyślnie nazwa // pakietu String servicename( ) default ""; // odwzorowane na // wsdl:service String wsdllocation( ) default ""; // używane gdy istnieje już // plik WSDL String portname( ) default ""; // odwzorowane na wsdl:port String endpointinterface( ) default ""; // deklaracja może być // oddzielona od // implementacji 21

22 Jeżeli bezstanowy komponent sesyjny oznacony nie posiada żadnej metody oznaczonej wtedy wszystrkie jego metody s ą udostępnione jako elementy usługi siecowej. W przeciwnym razie widoczne s ą tylko te oznaczone = RetentionPolicy.RUNTIME) WebMethod{ String operationname( ) default ""; // wsdl:operation, // domyślnie nazwa metody String action( ) default ""; // nazwa akcji SOAP 22

23 umożliwia dalsz ą kontrol ę WSDL'a generowanego dla metody oznaczonej WebParam { public enum Mode {IN, OUT, INOUT; String name() default ""; // odwzorowywane na wsdl:part String targetnamespace() default ""; Mode mode() default Mode.IN; boolean header() default false; // parametr w nagłówku SOAP // zamiast w treści (body) 23

24 Adnotacja = "CheckStatus") public int = "ReservationID") String = "CustomerID", mode = WebParam.Mode.OUT) javax.xml.ws.holder<integer> customerid){ <message name="checkstatus"> <part name="reservationid" type="xsd:string"/> </message> <message name="checkstatusresponse"> <part name="return" type="xsd:int"/> <part name="customerid" type="xsd:int"/> </message> <porttype name="travelagent"> <operation name="checkstatus" parameterorder="reservationid CustomerID"> <input message="tns:checkstatus"/> <output message="tns:checkstatusresponse"/> </operation> </porttype> 24

25 Adnotacja = = "ReservationID") // oprócz name może zawierać // także targetnamespace() public String makereservation() { <xs:element name="reserveresponse" type="reserveresponse"/> <xs:complextype name="reserveresponse"> <xs:sequence> <xs:element name="reservationid" type="xs:string" nillable="true"/> </xs:sequence> </xs:complextype> <message name="reserveresponse"> <part name="parameters" element="tns:reserveresponse"/> </message> <porttype name="travelagent"> <operation name="reserve"> <input message="tns:reserve"/> <output message="tns:reserveresponse"/> </operation> </porttype> 25

26 Inne pozwala dookreślić postać wywoła ń = = RetentionPolicy.RUNTIME) SOAPBinding { public enum Style {DOCUMENT, RPC; // parametry mapowane na wsdl:part public enum Use {LITERAL,ENCODED; public enum ParameterStyle {BARE, // jeden parametr w elemencie // root określający całą // wiadomość WRAPPED; // wiele parametrów // w elemencie root Style style() default Style.DOCUMENT; Use use() default Use.LITERAL; //LITERTAL wymagane przez JAX-WS ParameterStyle parameterstyle() default w odpowiedzi przesyłana jest pusta wiadomość: brak elementu output w WSDL'u, 26

27 Rozdzielenie interfejsu i implementacji package com.titan.webservice; import public interface TravelAgentEndpoint{ public String makereservation(int cruiseid, int cabinid, int customerid, double price); package com.titan.webservice; import = "com.titan.webservice.travelagentendpoint") public class TravelAgentBean implements TravelAgentEndpoint { 27

28 Punkt końcowy usługi Podobnie jak w JAX-RPC dostęp do usługi sieciowej realizowanej np. przez komponent EJB może być zrealizowany poprzez interfejs końcowy usługi i klas ę usługi: package com.charge_it; import javax.jws.webservice; = SOAPBinding.Style.RPC) public interface Processor{ public int charge(string name, String number, java.util.calendar expdate, String cardtype, float amount); 28

29 Klasa usługi package com.charge_it; import javax.xml.ws.webserviceclient; import targetnamespace=" wsdllocation=" public class ProcessorService extends javax.xml.ws.service { public ProcessorService( ) { super(new URL(" new QName(" public ProcessorService(String wsdlloc, QName sname){ super(wsdlloc, = "ProcessorPort") public Processor getprocessorport( ) { return (Processor) super.getport(new QName(" 29

30 Dostęp do public class AnyBean implements AnyRemote Processor processor; public void amethod() throws EJBException { try { processor.charge(customername, card.number, expdate, card.type, price); catch(exception e) { throw new EJBException(e); 30

31 Podsumowanie Usługi sieciowe, ze względu na swoj ą elastyczność i uniwersalność zyskały bardzo mocn ą pozycj ę w środowisku aplikacji biznesowych. Większość rozwiąza ń integrujących różne systemy opiera si ę właśnie na usługach sieciowych. Specyfikacja JavaEE umożliwia tworzenie komponentów realizujących tekie usługi jak równie ż korzystanie z nich. Jest to możliwe za pośrednictwem dwóch mechanizmów: JAX- RPC i JAX-WS. 31