Temat Stworzenie systemu składającego się z prostej usługi sieciowej (ang. web service) oraz komunikującej się z nią aplikacji klienckiej umożliwiającej dostęp do usługi przez przeglądarkę internetową. Cele 1. Zapoznanie się z podstawowymi elementami składającymi się na kompletny system usługi sieciowej dostępnej dla użytkowników przez przeglądarkę internetową; przeprowadzenie przy użyciu środowiska Oracle9i JDeveloper procesu implementacji kodu takiej aplikacji obejmującego kolejne etapy: - konfiguracja środowiska programistycznego oraz serwerowego, - opublikowanie usługi sieciowej (przygotowanej uprzednio w postaci gotowego kodu źródłowego), - implementacja aplikacji klienckiej działającej w środowisku tworzenia aplikacji (za pośrednictwem modułu typu web service stub) lub dostępnej zdalnie przy użyciu przeglądarki internetowej. 2. Zapoznanie się z funkcjonalnościami środowiska wspomagającego tworzenie aplikacji usług sieciowych. Zadania 1. Uruchomić i skonfigurować środowisko tworzenia aplikacji i serwer aplikacji. 1.1. Uruchomić serwer aplikacji Oracle9iAS Containers for J2EE (zmienić aktualny katalog na \jdev903\j2ee\home, a następnie uruchomić serwer w środowisku maszyny wirtualnej Java poleceniem..\..\jdk\bin\java jar oc4j.jar). 1.2. Uruchomić środowisko tworzenia aplikacji Oracle9i JDeveloper. 1.3. Utworzyć i przetestować połączenie pomiędzy środowiskiem Oracle9i JDeveloper a serwerem Oracle9iAS Containers for J2EE. 1.3.1. Utworzyć nowe połączenie typu Oracle9iAS-StandAlone (Connections->Application Server->New Connection->Oracle9iAS-StandAlone). 1.3.2. Ustawić identyfikator użytkownika (Username) jako "admin", a hasło jako "welcome" jednocześnie zaznaczając opcję "Deploy Password. 1.3.3. Ustawić lokalizację URL jako ormi://127.0.0.1/. 1
1.3.4. Ustawić opcję Target Web Site jako http-web-site. 1.3.5. Jako wartość pola Local Directory Where admin.jar for Oracle9iAS is installed" wskazać lokalizację pliku admin.jar (zwykle w katalogu \j2ee\home). 1.3.6. Przetestować utworzone połączenie. 2. Uruchomić (opublikować) i przetestować prostą aplikację sieciową 2.1. Otworzyć plik przestrzeni roboczej zawierającej gotowy kod źródłowy prostej usługi sieciowej (\statelessnew\workspacestatelessjava.jws) 2.2. Zlokalizować i zapoznać się z zawartością pliku zawierającego kod źródłowy klasy, której metoda udostępniana jest jako implementowana w ramach ćwiczenia usługa sieciowej; opisać przewidywane działanie usługi sieciowej 2.3. Utorzyć postać wykonywalną (Make) zlokalizowanej klasy. 2.4. Do struktury projektu (ProjectStateless.Java.jpr) dodać usługę sieciową wraz z definicjami potrzebnymi do jej opublikowania (General->Web Service->Java Web Service) przy użyciu wizualnego komponentu środowiska JDeveloper Web Service Publishing Wizard. 2.4.1. W pierwszym kroku procedury Web Service Publishing Wizard zlokalizować klasę HelloImpl jako wartość pola Select the class that you want to publish as a Web service. 2.4.2. W drugim kroku procedury Web Service Publishing Wizard wybrać metodę sayhello jako udostępnianą usługę sieciową. 2.4.3. W trzecim kroku procedury Web Service Publishing Wizard zaakceptować domyślne lokalizacje generowanego pliku WSDL, generowanego pliku definiującego proces publikacji usługi sieciowej (web.xml) i punktu końcowego usługi sieciowej (ang. web service endpoint) oraz domyślną konfigurację portu serwera WWW oraz wybór konfiguracji połączenia z serwerem aplikacji (Oracle9iAS-StandAlone). 2.5. Zapoznać się z zawartością i określić działanie wygenerowanych przez Web Service Publishing Wizard plików: HelloImpl.wsdl i web.xml 2.6. Opublikować stworzoną usługę sieciową (tj. serwlet komunikacji SOAP wraz z klasą Java HelloImpl) zgodnie z informacjami zawartymi w profilu WebServices.deploy wybierając opcję Oracle9iAS_Standalone. 3. Uruchomić i przetestować aplikację kliencką usługi sieciowej 3.1. Do struktury projektu (ProjectStateless.Java.jpr) dodać aplikację kliencką utworzonej usługi sieciowej (New->General->Web Service-> Web Service Stub/Skeleton) 2
3.1.1. Użyć procedury Web Service Stub/Skeleton Wizard (automatyczne generowanie kodu). Skorzystać z automatycznego generowania metody głównej. Zaobserwować wynik analizy pliku WSDL prezentowany przez środowisko Oracle9i JDeveloper w postaci listy metod udostępnianych przez usługę sieciową. 3.1.2. Kontynuować procedurę automatycznego generowania kodu przez wybranie odpowiedniej metody. 3.1.3. Zapoznać się z wygenerowanym kodem - klasami, ich wzajemnymi zależnościami i głównym przeznaczeniem (ze szczególnym uwzględnieniem komunikacji przy użyciu protokołu SOAP). 3.1.4. W odpowiednim miejscu kodu klasy HelloImplStub.java dodać następującą linię: System.out.println(stub.sayHello("Test")); 3.2. Uruchomić klasę HelloImplStub.java i zaobserwować wynik jej działania (w oknie typu log). 3.3. Użyć narzędzia Tools->TCP Packet Monitor w celu śledzenia komunikatów języka SOAP wymienianych pomiędzy serwerem a klientem w procesie korzystania z usługi sieciowej. 3.3.1. Zainicjować tryb śledzenia komunikacji (Start TCP Packet Monitor >). 3.3.2. Ponownie uruchomić klasę HelloImplStub.java. 3.3.3. Zapoznać się z zapisem przepływu komunikatów przedstawionym na zakładce History oraz z zawartością poszczególnych komunikatów przedstawioną na zakładce Data; porównać ją z przykładami z załącznika. 3.4. Przetestować działanie aplikacji przy użyciu przeglądarki internetowej. 3.4.1. Wywołać okno edycji właściwości usługi sieciowej (Edit), a następnie po wybraniu zakładki File Locations (w obrębie Web Service Publishing Wizard) zaznaczyć i skopiować zawartość pola określającego adres punktu końcowego usługi sieciowej (ang. web service endpoint). 3.4.2. Uruchomić przeglądarkę internetową i korzystając z uprzednio skopiowanej wartości uzyskać dostęp do punktu końcowego usługi sieciowej. 3.4.3. Zapoznać się z działaniem uruchomionej aplikacji klienckiej wykorzystując dostęp lokalny jak i zdalny (przy pomocy innego komputera znajdującego się w sieci lokalnej). Załącznik Przykładowa postać dokumentu WSDL (HelloImpl.wsdl) opisującego implementowaną usługę sieciową (w przypadku różnych implementacji wartość pola soap:address location jest zmienna): 3
<?xml version = '1.0' encoding = 'UTF-8'?> <!--Generated by the Oracle9i JDeveloper Web Services WSDL Generator- -> <!--Date Created: Sat Nov 01 13:21:36 CET 2003--> <definitions name="helloimpl" targetnamespace="http://helloimpl.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://helloimpl.wsdl" xmlns:ns1="http://ihelloimpl.xsd"> <types> <schema </types> targetnamespace="http://ihelloimpl.xsd" xmlns="http://www.w3.org/2001/xmlschema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"/> <message name="sayhello0request"> <part name="param" type="xsd:string"/> </message> <message name="sayhello0response"> <part name="return" type="xsd:string"/> </message> <porttype name="helloimplporttype"> <operation name="sayhello"> <input name="sayhello0request" message="tns:sayhello0request"/> <output name="sayhello0response" message="tns:sayhello0response"/> </operation> 4 </porttype>
<binding name="helloimplbinding" type="tns:helloimplporttype"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sayhello"> <soap:operation soapaction="" style="rpc"/> <input name="sayhello0request"> <soap:body use="encoded" namespace="helloimpl" encodingstyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output name="sayhello0response"> <soap:body use="encoded" namespace="helloimpl" encodingstyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> <service name="helloimpl"> <port name="helloimplport" binding="tns:helloimplbinding"> <soap:address location="http://127.0.0.1:8888/workspacestatelessjava- ProjectStatelessJava-context-root/HelloImpl"/> </port> </service> </definitions> Przykładowa postać dokumentu IHelloImpl.java opisującego interfejs implementowanej usługi sieciowej poprzez odwołania metod publicznych klasy wskazanej przez programistę podczas wspomaganego przez środowisko Oracle9i JDeveloper procesu tworzenia usługi: IHelloImpl.java /** * Generated by the Oracle9i JDeveloper Web Services Interface Generator * Date Created: Sat Nov 01 13:21:37 CET 2003 5
* * This interface lists the subset of public methods that you * selected for inclusion in your web service's public interface. * It is referenced in the web.xml deployment descriptor for this service. * * This file should not be edited. */ public interface IHelloImpl public String sayhello(string param); Przykładowa postać dokumentu HelloImpl.java zawierającego klasę o metodzie publicznej sayhello udostępnianej implementowanej w ramach ćwiczenia usłudze sieciowej: public class HelloImpl public HelloImpl() public String sayhello(string param) return "Hello " + param + "! The current time is " + new java.util.date(); Przykładowa postać dokumentu HelloImplStub.java zawierającego kod klienta protokołu SOAP wchodzącego w skład aplikacji klienckiej komunikujacej się z implementowaną w ramach ćwiczenia usługą sieciową (w zależności od różnych lokalizacji, w których usługa sieciowa może być zaimplementowana (opublikowana) zmienna jest wartość pola endpoint): import oracle.soap.transport.http.oraclesoaphttpconnection; 6
import org.apache.soap.encoding.soapenc.beanserializer; import org.apache.soap.encoding.soapmappingregistry; import org.apache.soap.util.xml.qname; import java.net.url; import org.apache.soap.constants; import org.apache.soap.fault; import org.apache.soap.soapexception; import org.apache.soap.rpc.call; import org.apache.soap.rpc.parameter; import org.apache.soap.rpc.response; import java.util.vector; import java.util.properties; /** * Generated by the Oracle9i JDeveloper Web Services Stub/Skeleton Generator. * Date Created: Sat Nov 01 13:29:37 CET 2003 * WSDL URL: file:/c:/pp/webservices/cwiczenie_2/statelessnew/project/src/helloimp l.wsdl */ public class HelloImplStub public HelloImplStub() m_httpconnection = new OracleSOAPHTTPConnection(); m_smr = new SOAPMappingRegistry(); public static void main(string[] args) try 7
HelloImplStub stub = new HelloImplStub(); // Add your own code here. System.out.println(stub.sayHello("Test")); catch(exception ex) ex.printstacktrace(); public String endpoint = "http://127.0.0.1:8888/workspacestatelessjava-projectstatelessjavacontext-root/helloimpl"; private OracleSOAPHTTPConnection m_httpconnection = null; private SOAPMappingRegistry m_smr = null; public String sayhello(string param) throws Exception String returnval = null; URL endpointurl = new URL(endpoint); Call call = new Call(); call.setsoaptransport(m_httpconnection); call.settargetobjecturi("helloimpl"); call.setmethodname("sayhello"); call.setencodingstyleuri(constants.ns_uri_soap_enc); Vector params = new Vector(); 8
params.addelement(new Parameter("param", java.lang.string.class, param, null)); call.setparams(params); call.setsoapmappingregistry(m_smr); Response response = call.invoke(endpointurl, ""); if (!response.generatedfault()) else Parameter result = response.getreturnvalue(); returnval = (String)result.getValue(); Fault fault = response.getfault(); throw new SOAPException(fault.getFaultCode(), fault.getfaultstring()); return returnval; public void setmaintainsession(boolean maintainsession) m_httpconnection.setmaintainsession(maintainsession); public boolean getmaintainsession() return m_httpconnection.getmaintainsession(); 9
public void settransportproperties(properties props) m_httpconnection.setproperties(props); public Properties gettransportproperties() return m_httpconnection.getproperties(); Przykładowa postać dokumentu web.xml stanowiącego specyfikację sposobu implementacji usługi sieciowej, tj. zawierającego kod konfigurujacy predefiniowaną klasę serwletu oracle.j2ee.ws.statelessjavarpcwebservice, który służy przetwarzaniu komunikatów SOAP i komunikacji z wyżej położoną instancją klasy HelloImpl: <?xml version = '1.0' encoding = 'windows-1250'?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <description>generated by the Oracle9i JDeveloper Web Services WebXML Generator</description> <servlet> <servlet-name>helloimpl</servlet-name> <servletclass>oracle.j2ee.ws.statelessjavarpcwebservice</servlet-class> <init-param> <param-name>class-name</param-name> <param-value>helloimpl</param-value> </init-param> 10
<init-param> <param-name>interface-name</param-name> <param-value>ihelloimpl</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>helloimpl</servlet-name> <url-pattern>/helloimpl</url-pattern> </servlet-mapping> </web-app> Przykładowa treść komunikatu SOAP typu Request: <?xml version = '1.0' encoding = 'UTF-8'?><SOAP-ENV:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema"> <SOAP-ENV:Body> <ns1:sayhello xmlns:ns1="helloimpl" SOAP- ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <param xsi:type="xsd:string">mike</param> </ns1:sayhello> </SOAP- ENV:Body></SOAP-ENV:Envelope> Przykładowa treść komunikatu SOAP typu Response: <?xml version = '1.0' encoding = 'UTF-8'?><SOAP-ENV:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema"> <SOAP-ENV:Body> <ns1:sayhelloresponse xmlns:ns1="helloimpl" SOAP- ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <return xsi:type="xsd:string"> Hello Mike! The current time is Sun Jun 23 23:41:27 PDT 2002 </return> </ns1:sayhelloresponse> </SOAP-ENV:Body></SOAP-ENV:Envelope> 11