122
Web Services Praktyczny przewodnik Robert Nowak Vercom Sp z o. o. 21 wrze´ snia 2005

Web Services Praktyczny przewodnik - Robert Nowakrobertnowak.pl/publikacje/WebServices.pdf · Web Services Praktyczny przewodnik Robert Nowak Vercom Sp z o. o. 21 wrze·snia 2005

  • Upload
    lyminh

  • View
    236

  • Download
    4

Embed Size (px)

Citation preview

Web ServicesPraktyczny przewodnik

Robert NowakVercom Sp z o. o.

21 wrzesnia 2005

Spis tresci

1 Web Services - tworzenie i uzytkowanie 41.1 Definicja Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2 Przykłady uzycia Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.2.1 Rozbudowa dotychczasowych aplikacji . . . . . . . . . . . . . . . . . . . . . . . 41.2.2 Pozyskanie informacji z Google . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.2.3 Współpraca z baza danych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.2.4 Ksiegarnia amazon.com . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.2.5 BPEL - jezyk zarzadzania Web Services . . . . . . . . . . . . . . . . . . . . . . . 10

1.2.5.1 Podstawowe własciwosci jezyka . . . . . . . . . . . . . . . . . . . . . 101.2.5.2 Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1.2.6 ebXML - XML dla biznesu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.3 Protokół SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1.3.1 Opis protokołu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.3.2 Szkielet komunikatu SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1.3.2.1 Koperta (envelope) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.3.2.2 Nagłówek (header) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.3.2.3 Ciało (body) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141.3.2.4 Bład (fault) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

1.3.3 Przykładowa para komunikatów . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.4 Format WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

1.4.1 Przykładowy listing WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161.5 UDDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2 Web Services z wykorzystaniem Apache Axis 212.1 Co to jest Axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.2 Instalacja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.2.1 Wymagane oprogramowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.2.2 Pobranie Axisa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.2.3 Instalacja pakietu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.2.3.1 Opcjonalna instalacja parsera XML . . . . . . . . . . . . . . . . . . . . 222.2.3.2 Uzycie Axis 1.2 razem z WebLogic 8.1 . . . . . . . . . . . . . . . . . . 22

2.2.4 Ustawienie zmiennych systemowych . . . . . . . . . . . . . . . . . . . . . . . . 222.2.5 Sprawdzenie instalacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.3 Struktura katalogów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242.4 Korzystanie z Axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.4.1 Lista uruchomionych serwisów . . . . . . . . . . . . . . . . . . . . . . . . . . . 242.4.2 Dodawanie własnych serwisów . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

2.4.2.1 Udostepnianie Web Services za pomoca plików JWS . . . . . . . . . . 252.4.2.2 Rozbudowana metoda udostepniania Web Services . . . . . . . . . . . . 25

2.5 Pisanie aplikacji serwera z wykorzystaniem Axis . . . . . . . . . . . . . . . . . . . . . . 252.5.1 Uzycie plików .JWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

2.5.1.1 Tworzenie kodu zródłowego . . . . . . . . . . . . . . . . . . . . . . . . 25

1

SPIS TRESCI 2

2.5.1.2 Udostepnianie klasy . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262.5.1.3 Łaczenie sie z Web Service za pomoca URL . . . . . . . . . . . . . . . 282.5.1.4 Testowanie udostepnionych metod . . . . . . . . . . . . . . . . . . . . 29

2.5.2 Metoda zaawansowana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312.5.2.1 Tworzenie kodu zródłowego . . . . . . . . . . . . . . . . . . . . . . . . 312.5.2.2 Udostepnianie serwisu . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

2.6 Pisanie aplikacji klienta z wykorzystaniem Axis . . . . . . . . . . . . . . . . . . . . . . . 362.6.1 Klient statyczny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

2.6.1.1 Generacja plików Java z WSDL . . . . . . . . . . . . . . . . . . . . . . 362.6.1.2 Tworzenie kodu klienta . . . . . . . . . . . . . . . . . . . . . . . . . . 372.6.1.3 Kompilacja kodu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372.6.1.4 Uruchomienie klienta . . . . . . . . . . . . . . . . . . . . . . . . . . . 372.6.1.5 Kod klienta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

2.6.2 Klient dynamiczny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382.6.2.1 Tworzenie kodu zródłowego . . . . . . . . . . . . . . . . . . . . . . . . 382.6.2.2 Kod klienta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

2.7 Pliki do pobrania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

3 Tworzenie i korzystanie z Web Services w PHP 433.1 Wstep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433.2 Wbudowany SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

3.2.1 Instalacja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433.2.2 Konfiguracja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463.2.3 Tworzenie serwera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463.2.4 Tworzenie klienta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

3.3 PEAR SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473.3.1 Instalacja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.3.2 Tworzenie serwera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.3.3 Klient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

3.4 Pliki do pobrania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

4 Web Services z uzyciem Eclipse Web Tools Platform 544.1 Wstep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544.2 Uzyte komponenty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544.3 Instalacja Web Tools Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544.4 Programowanie Web Services z uzyciem WTP . . . . . . . . . . . . . . . . . . . . . . . . 63

4.4.1 Tworzenie nowego projektu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644.4.2 Tworzenie Web Service z klas Javy (bottom-up WS) . . . . . . . . . . . . . . . . 704.4.3 Tworzenie Web Service z pliku WSDL (top-down WS) . . . . . . . . . . . . . . . 784.4.4 Tworzenie klienta Web Service przy pomocy WTP . . . . . . . . . . . . . . . . . 834.4.5 Klasa wykorzystujaca wygenerowany kod klienta (klient statyczny) . . . . . . . . 894.4.6 Web Service na zdalnym serwerze (eksport projektu do pliku WAR) . . . . . . . . 924.4.7 Testowanie WS uzywajac Web Services Explorer . . . . . . . . . . . . . . . . . . 994.4.8 Testowanie Web Service za pomoca URL . . . . . . . . . . . . . . . . . . . . . . 109

4.5 Pliki do pobrania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

5 Web Services i Googletworzenie klienta 1115.1 Wstep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1115.2 Uzycie dostarczonych bibliotek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1115.3 Klient Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1125.4 Klient w PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1155.5 Pliki do pobrania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

SPIS TRESCI 3

6 Dodatki 1206.1 Słowniczek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

6.1.1 XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1206.1.2 J2EE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

Rozdział 1

Web Services - tworzenie i uzytkowanie

1.1 Definicja Web ServicesWeb Services to zbiór standardów stworzony w celu wspierania wymiany informacji za pomoca sieci.

Standardy te tworza abstrakcyjna warstwe, znajdujaca sie ponad systemami operacyjnymi czy tezjezykami programowania, umozliwiajac porozumiewanie sie aplikacji bez kłopotania sie o szczegóły im-plementacyjne. Format i sposób wymiany komunikatów miedzy serwisami jest dokładnie okreslony zapomoca standardów W3C (http://w3c.org).

Kazdy serwer posiada dodatkowo reguły okreslajace sposób komunikacji z nim (stosowane zabez-pieczenia, adres własciwego serwisu) oraz liste udostepnianych metod wraz z argumentami i zwracanymitypami. Wszystko to jest opisane za pomoca dokumentu WSDL (1.4). Inne komputery współpracuja zWeb Service na zasadach okreslonych w tym dokumencie, uzywajac komunikatów, które moga byc za-warte w kapsułce SOAP (1.3), lub tez stosowac format REST. Komunikaty sa zazwyczaj przekazywanez wykorzystaniem protokołu HTTP. Ich budowa opiera sie o XML (6.1.1), z mozliwymi połaczeniami zinnymi standardowymi dokumentami sieciowymi.

Aplikacje stworzone w róznych jezykach programowania, działajace na róznych platformach sprze-towych i programistycznych moga dzieki Web Services komunikowac sie ze soba poprzez siec tak łatwojakby działo sie to pomiedzy lokalnymi procesami (rysunek 1.1). Ta przenosnosc jest mozliwa dzieki uzy-ciu otwartych standardów, które tworza OASIS razem z W3C. Stanowi ona o wielkiej sile Web Services,które powoli zdaja sie przejmowac prym w komunikacji miedzy aplikacjami sieciowymi.

1.2 Przykłady uzycia Web ServicesWeb Services słuza znacznemu usprawnieniu współpracy na linii klient-serwer. W prosty sposób udostep-niaja usługi, jak równiez potrafia sie z nimi łaczyc i z nich korzystac. Mozna by powiedziec ze to zadnanowosc i byłaby to prawda. Mamy strony WWW które przekazuja informacje, kanały RSS itp. WebServices nie sa czyms rewolucyjnym jesli chodzi o cel istnienia, jednak sposób ich pracy stanowi wielkikrok w strone ułatwienia i ustandaryzowania współpracy serwisów. Ich zastosowania sa bardzo szerokie -mozna z nich z powodzeniem korzystac wszedzie tam gdzie potrzebna jest komunikacja w celu pobraniadanych.

1.2.1 Rozbudowa dotychczasowych aplikacjiWyobrazmy sobie przykładowa firme, gdzie ze wzgledu na niezawodnosc, serwer z najnowszymi danymifirmowy ma zostac uruchomiony na bazie danych PostgreSQL. Jednak wszystkie wczesniejsze dane saw aplikacji napisanej w .NET i umieszczone w bazie danych MSSQL. Stworzenie komunikacji miedzyaplikacja .NET a Javowa jest trudna sprawa, a jej wypracowanie zajełoby miesiace.

Bez uzycia Web Services byłaby to trudna sytuacja, jednak dzieki nim, mozliwe jest eleganckie inowoczesne rozwiazanie: serwer MSSQL pozostaje na swoim miejscu, a na platformie .NET uruchomionej

4

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 5

Rysunek 1.1: Idea Web Services

na tym samym komputerze, zostaje udostepniony Web Service, wstawiajacy funkcje dostepu do MSSQL.Powstaje tez aplikacja napisana w jezyku Java. Łaczy sie ona z baza PostgreSQL, a takze z Web Service.NET’u. Z tej aplikacji korzysta klient. Oto schemat tej struktury:

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 6

Rysunek 1.2: Integracja .NET z Java

Przesledzmy typowe wykorzystanie: uzytkownik korzysta z aplikacji napisanej w Javie: wybiera zmenu potrzebne mu informacje (1). Aplikacja analizuje dane i widzi, ze potrzebuje danych z obu bazdanych. Łaczy sie wiec z Web Service udostepnionym przez .NET i przekazuje mu zadanie (2). WebService uruchamia odpowiednie procedury .NET, który pobiera z bazy MSSQL odpowiednie wiadomosci(3, 4). Dane zostaja odesłane do Javy (5). Nastepnie pobierane sa informacje z PostgreSQL (6,7), nastepujeich przetworzenie i klient dostaje wynik (8).

Jak widac, integracja przebiegła całkiem sprawnie. Ktos mógłby stwierdzic, ze to samo mozna byuzyskac innymi sposobami. To prawda, ale jak juz napisano wczesniej, pochłonełoby to duzo pracy i czasu.A my, dzieki zastosowaniu Web Services, mozemy bez trudu przeniesc nasza architekture na nastepnypoziom:

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 7

Rysunek 1.3: Integracja .NET z Java - Internet

Uzyskalismy teraz podział na dwie maszyny: jedna z zestawem .NET - MSSQL, druga J2EE - Post-greSQL. Powyzszy rozdział na dwa komputery połaczone tylko przez Internet staje sie mozliwy dzieki sileWeb Services. Powstaje pytanie: po co ryzykowac i kazac uzytkownikowi pracowac na serwerze? Po razkolejny korzystamy z Web Services:

Rysunek 1.4: Rozbudowa współpracy .NET z Java przez Internet

Kolejna korzysc wydaje sie byc naturalna: uzytkowników moze byc teraz wielu, kazdy z nich mozepracowac niezaleznie i równoczesnie.

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 8

Mysle ze ten akapit dobrze zaprezentował potencjał drzemiacy w Web Services.

1.2.2 Pozyskanie informacji z GoogleDo tej pory, chcac na przykład wykorzystac wyniki wyszukiwania zwracane przez Google, nalezało par-sowac kod HTML. Odpowiedzia na zapytanie

http://www.google.pl/search?hl=pl&q=p%C5%82yty+cd&btnG=Szukaj&lr=bała cała strona HTML. Pojedyncza pozycja (która trzeba równiez wyłowic z innych) wyglada nastepu-

jaco:

<!--m--><a href="http://www.emuzyka.pl/cd/"><b>PŁYTY</b> <b>CD</b>::<b>płyty</b><b>cd</b> na Emuzyka.pl.</a><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td style="width: 37em;" class="j"><font size="-1">Strona główna ? <b>płyty</b> <b>cd</b> ? 1,2, 3... Partnerem działu <b>płyty</b> <b>cd</b> na emuzyka.pl jestwww.merlin.com.pl? Startuj z emuzyka.pl ? Stare dzwonki zabronione! <b>...</b><br><font color="#008000">www.emuzyka.pl/<b>cd</b>/ -44k - 13 IX 2005 - </font><nobr><a class="fl"href="http://66.249.93.104/search?q=cache:HsLTXekgOLMJ:www.emuzyka.pl/cd/+p%C5%82yty+cd+&amp;hl=pl">Kopia</a>-<aclass="fl"href="/search?hl=pl&amp;lr=&amp;q=related:www.emuzyka.pl/cd/">Podobne&nbsp;strony </a><span> - </span><aclass="fl"cg_filter="http://www.emuzyka.pl/cd/"href="javascript:void(0);">Filter</a></nobr> </font><!--n-->

Zamienmy to moze w bardziej czytelna postac:

<!--m--><a href="http://www.emuzyka.pl/cd/">

<b>PŁYTY</b> <b>CD</b>::<b>płyty</b><b>cd</b>na Emuzyka.pl.</a>

<table border="0" cellpadding="0" cellspacing="0"><tbody>

<tr><td style="width: 37em;" class="j">

<font size="-1">Strona główna ? <b>płyty</b> <b>cd</b> ? 1, 2, 3...Partnerem działu <b>płyty</b> <b>cd</b> na emuzyka.pljest www.merlin.com.pl ? Startuj z emuzyka.pl ? Staredzwonki zabronione! <b>...</b><br>

<font color="#008000">www.emuzyka.pl/<b>cd</b>/ - 44k - 13 IX 2005 -

</font><nobr><a

class="fl"href="http://66.249.93.104/search?q=cache:HsLTXekgOLMJ:www.emuzyka.pl/cd/+p%C5%82yty+cd+&amp;hl=pl">Kopia

</a>-<a class="fl" href="/search?

hl=pl&amp;lr=

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 9

&amp;q=related:www.emuzyka.pl/cd/">Podobne&nbsp;strony

</a><span>-</span><a class="fl" cg_filter="http://www.emuzyka.pl/cd/"

href="javascript:void(0);">Filter

</a></nobr>

</font><!--n-->

Teraz z tego kodu nalezało wyciagnac potrzebne nam dane - np. URL (www.emuzyka.pl). Nawet gdy juzstworzono odpowiedni program, nalezało sie liczyc z tym, ze kazda zmiana w formacie wyszukiwaniaspowoduje koniecznosc uaktualnienia.

Chcac ułatwic współprace, Google stworzył i udostepnił własny Web Service: Google APIs. Terazcały kod odpowiedzialny za wykonanie zapytania i otrzymania URL wyglada nastepujaco (jezyk PHP):

$soapclient = new SoapClient(’http://api.google.com/GoogleSearch.wsdl’);$odpowiedz = $soapclient->

doGoogleSearch(key, ’płyty CD’, 0, 10,true, ’countryPL’, false, ’lang_PL’, ”,”);

$obecnyAdres = $odpowiedz->resultElements[$x]->URL;

W zmiennej $obecnyAdres mamy juz w tej chwili adres którego szukamy. Niezaleznie od przyszłych zmianw strukturze odpowiedzi, metoda ta zadziała. Za pomoca Google APIs mozna wykonac naprawde wielerzeczy - na przykład program do sprawdzania pozycji naszej strony w rankingu. Szerzej o tym programieoraz o Google APIs w rozdziale 5.4.

1.2.3 Współpraca z baza danychCiekawszy przykład uzycia to współpraca miedzy komponentami tej samej aplikacji. Przykładowo serwerWeb Services znajduje sie na maszynie z baza danych a klientem jest aplikacja w Javie. Zwyczajowoserwer musiał miec udostepniony interfejs dostepu do bazy, a klient odwoływac sie bezposrednio do niego,przesyłajac zapytania. Nie jest to zbyt bezpieczne, wymaga tez implementacji duzej czesci obsługi wkliencie.

Uzywajac Web Services, aplikacja łaczy sie z serwerem za pomoca prostego kodu (Java), nie martwiacsie o szczegóły:

Result res = new Result();res = service.getKsiazki(tytul, minCena, maksCena);System.out.println("Tytul ksiazki numer " + x + " to " +

res.getTytul() + " a cena " +res[x].getCena();

Zauwazmy, ze klient nie musi (a jesli serwer nie zechce to nie moze) wiedziec jakiego typu baze danychwykorzystano, czy tez w jakim jezyku programowania napisano aplikacje - jedyna interesujaca go rzeczajest odpowiedz na jego pytanie. Jesli dodac do tego mozliwosc zabezpieczenia usługi za pomoca zaawan-sowanych technik (szyfrowanie całosci i czesci przesyłanych komunikatów), otrzymujemy to, czym WebServices miały byc: nowa metoda sprawnej i bezpiecznej komunikacji miedzy aplikacjami.

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 10

1.2.4 Ksiegarnia amazon.comJeden z najwiekszych sklepów internetowych amazon.com równiez postanowił udostepnic swoje usługi zapomoca Web Services. Zostało to entuzjastycznie przyjete przez osoby zwiazane z serwisem.

Wydawcy ksiazek otrzymali narzedzie do monitorowania sprzedazy swoich i konkurencyjnychwydawnictw.Do tej pory wiele firm zbierało statystyki recznie (co przy duzej ilosci sprzedawanych pozycji wymagałoduzego nakladu pracy) albo tez parsujac HTML (o parsowaniu HTML napisano w punkcie 1.2.2).

Jednoczesnie własciciele stron internetowych otrzymali mozliwosc sprzedawania towarów amazon.combezposrednio ze swojego serwisu. Majac do dyspozycji Amazon Web Services, moga w prosty sposóbstworzyc kompleksowa oferte obejmujaca na przykład tylko dział sprzedazy pokrywajacy sie z tematykastrony. Odwiedzajacy moga przegladac taka oferte, a nawet wyszukiwac wewnatrz niej. Za kazdy zakupi-ony przedmiot, Amazon płaci odpowiednia marze włascicielowi serwisu przez który dokonano transakcji.

1.2.5 BPEL - jezyk zarzadzania Web ServicesBPEL, Business Process Execution Language jest jezykiem programowania opartym na XML. Jego zadaniemjest umozliwienie sprawnego i skoordynowanego przeprowadzenia transakcji ze jednym lub wiecej WebServices. Co najwazniejsze - serwisy te moga byc asynchroniczne i równoległe.

1.2.5.1 Podstawowe własciwosci jezyka

BPEL prezentuje logike odmienna od jezyków takich jak C++ czy Java. Jezyki te słuza do tworzeniaprogramów, w których czas wykonywania pojedynczych zadan jest krótki (sa one uruchamianie, wykonujaswoja, zazwyczaj lokalna, prace, a nastepnie koncza działanie).

BPEL jest jezykiem wysokopoziomowym ze zdolnoscia wykonywania tranzycji stanów. Oznacza to, zesystem składa sie z pewniej liczby (byc moze nieskonczonej) stanów w których moze sie znalezc oraz regułprzejsc miedzy nimi. W praktyce oznacza to, ze jest nim mozliwa obsługa asynchronicznych komunikatów,czy tez wprowadzenie reguły ACID.

Asynchroniczne komunikaty w uproszczeniu sa to wiadomosci na które oczekujemy nieznana, aleskonczona ilosc czasu. Przykładowo aplikacja wysyłajaca wniosek o pozyczke do banku w koncu otrzymaw koncu odpowiedz (zakładajac niezawodnosc banku i transmisji), ale moze ja otrzymac dopiero pokilku dniach. Nasza aplikacja zmieni wtedy stan na odpowiedni do sytuacji, przechodzac na przykładdo wczesniej ustalonego zakupu posiadłosci za pozyczone pieniadze w razie udzielenia kredytu, lub dowynajecia mieszkania w razie odmowy.

Nazwa reguły ACID jest skrótem od angielskich słów Atomicity (atomowosc), Consistency (spójnosc),Isolation (izolacja), Durability (trwałosc). Sa to wazne zasady wziete z dziedziny baz danych gwarantujacezachowanie poprawnosci przetwarzanych danych. Cztery zadania reguły oznaczaja:

• atomowosc - dana czynnosc jest wykonana cała, albo w ogóle. Jesli zazadamy skopiowania danychz dysku A na dysk B, albo zostana skopiowane wszystkie dane, albo zadne. Nawet jesli połowaplików bedzie zapisana juz na dysku A gdy wydarzy sie awaria, kopiowanie zostanie cofniete, adane usuniete.

• spójnosc - jesli system był zgodny z okreslonymi regułami przed operacja, po operacji bedzie równiezzgodny

• izolacja - jesli dwa lub wiecej procesów wykonuje sie równoczesnie, kazdy działa osobno. Przykład:jesli oba korzystaja z jednej zmiennej, kazdy z nich widzi jej własna wersje, zmieny wykonane wprocesie A nie zmienia zmiennej w procesie B. Istnieja jednak tak zwane poziomy izolacji, gdzieniektóre załozenia sa modyfikowane.

• trwałosc - dane sa poprawne przez cały czas. Nawet jesli wskutek awari wykonana zostanie tylkoczesc operacji, co moze spowodowac powstanie niepoprawnego stanu, system bedzie potrafił okreslicdokładnie w którym miejscu nastapiła awaria i podjac odpowiednie kroki

Obecnie dostepne sa juz narzedzia, które pozwalaja na tworzenie schematów przepływu obsługi w jezykuBPEL za pomoca technologii ’przeciagnij i upusc’.

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 11

1.2.5.2 Podsumowanie

Podsumowujac, dzieki jezykowi BPEL jestesmy, jak w powyzszym przykładzie banku, połaczyc wiele os-obnych serwisów (składanie wniosków, obsługa przelewów pieniedzy, agencja wynajmu nieruchomosci,posrednik zakupu posiadłosci) w jedna logicznie powiazana całosc. Dodatkowo otrzymujemy takie mech-anizmy jak definiowanie współbieznosci, zarzadzanie zdarzeniami i wyjatkami czy tez mainpulacja struk-turami.

Plugin pozwalajacy dodanie obsługi jezyka BPEL do Eclipse znajduje sie pod adresem http://www.oracle.com/technology/products/ias/bpel/index.html .

1.2.6 ebXML - XML dla biznesuebXML, electronic business XML jest rodzina standardów XML tworzonych przez OASIS i UN/CEFACTktórych celem jest dostarczenie otwartej i opartej o XML infrastruktury która umozliwi swiatowa wymianeinformacji biznesowej w niezalezny od systemu operacyjngo, bezpieczny i sprecyzowany sposób. Standardzostał zbudowany na podstawie wieloletnich doswiadczen biznesu elektronicznego, tak by w mozliwienajprostszy sposób pokryc wymagania rozwijajacego sie przemysłu.

Jedna z ciekawszych propozycji jezyka jest tworzenie profilu firmy, a nastepnie automatyczne znajdy-wanie partnera biznesowego z odpowiadajacym nam profilem.

1.3 Protokół SOAPKomunikacja miedzy serwerem a klientem odbywa sie za pomoca protokołu SOAP. Specyfikacja standarduSOAP znajduje sie pod adresem http://www.w3.org/TR/soap/ . Tutaj wyjasnimy tylko pokrótce czymjest SOAP i przedstawimy przykładowy komunikat SOAP i odpowiedz na niego.

1.3.1 Opis protokołuSOAP jest to protokół słuzacy do wymiany informacji w zdecentralizowanym, rozproszonym srodowisku.Uzywa technologii XML aby zdefiniowac rozszerzalna platforme pozwalajaca na wymiane komunikatówza pomoca róznych standardowych protokółów (np. HTTP). Platforma z załozenia jest niezalezna odjezyka programowania i innych szczegółów implementacyjnych. Protokół SOAP składa sie z trzech głównychczesci:

• koperty (envelope) która okresla szkielet opisujacy co znajduje sie w komunikacie i jak go przetwarzac,

• zbioru reguł kodujacych potrzebnych do rozszyfrowania typów danych (równiez złozonych) zdefin-iowanych wewnatrz aplikacji,

• reguł dotyczacych wywoływania zdalnych procedur i odczytu odpowiedzi.

Bardziej ludzko mozna by powiedziec, ze SOAP jest jezykiem jakim porozumiewaja sie Web Services,zbudowanym na podstawie jezyka XML (6.1.1), co umozliwia jego uniezaleznienie do uzytych systemówoperacyjnych czy tez jezyków programowania. Jego budowa jest okreslona przez standardy, a ich za-chowanie gwarantuje poprawna wymiane informacji.

Omówmy teraz dokładnie budowe komunikatu SOAP.

1.3.2 Szkielet komunikatu SOAPOgólny szkielet prezentuje sie nastepujaco:

<?xml version="1.0"?><soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 12

...

...naglowek...

...</soap:Header><soap:Body>......glowna czesc komunikatu......<soap:Fault>

...

...bledy, o ile wystapily...

...</soap:Fault>

</soap:Body></soap:Envelope>

Opiszemy teraz jego kolejne fragmenty

1.3.2.1 Koperta (envelope)

Element wymagany.Koperta to główna czesc komunikatu SOAP, inne elementy jak nagłówek czy ciało sa jej potomkami.

Koperta definiuje dokument XML jako komunikat SOAP.Składnia:

<?xml version="1.0"?><soap:Envelope

...Tresc komunikatu...

</soap:Envelope>

Atrybut xmlns:soap (opcjonalny) wskazuje przestrzen nazw (schemat według jakiego decydujemy sie bu-dowac komunikat, w przykładzie podano standardowy zestaw dla SOAP 1.2 zdefioniowany przez W3C,ale mozliwe jest defioniowanie własnych dokumentów).

Składnia:

xmlns:soap="URL"

Atrybut encodingStyle (obowiazkowy) słuzy do definicji typów danych uzywanych w dokumencie. Tenatrybut moze pojawic sie w kazdym elemencie komunikatu i zostanie zastosowany w tym elemencie iwszystkich jego podelemnetach. Komunikat SOAP nie ma domyslnej wartosci tego atrybutu, dlategonalezy go podac przynajmniej raz, w głównym elemencie.

Składnia:

soap:encodingStyle="URL"

Prawidłowo zdefiniowane atrybuty to przykładowo:

<?xml version="1.0"?><soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">...Tresc komunikatu...

</soap:Envelope>

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 13

Nazwa Wykonywanienext Musi byc wykonany przez wszystkie wezłynone Nikt nie moze tego wykonac

ultimateReceiver Koncowy wezeł nie moze tego wykonacwłasna reguły okreslone w URL

Tablica 1.2: Wykonanie poszczególnych ról

1.3.2.2 Nagłówek (header)

Element opcjonalny.Nagłówek zawiera wiadomosci okreslajace dodatkowe własciwosci komunikatu. Moga to byc na

przykład elementy dotyczace bezpieczenstwa czy tez reguły przetwarzania ciała. Jesli podano nagłówek,musi zostac wpisany jako pierwszy na liscie potomków koperty.

Przykład:

<?xml version="1.0"?><soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"><soap:Header>...Dane naglowka...</soap:Header>......

</soap:Envelope>

Atrybut actor (opcjonalny) (w SOAP wersja 1.2 role) okresla odbiorce, a własciwie wykonawce danegoelementu. Komunikaty SOAP moga podrózowac przez siec, przechodzac po drodze przez wiele wezłów(komputerów). Atrybut actor okresla kto ma go (element nagłówka) wykonywac:

Nazwa Pełna nazwanext "http://www.w3.org/2003/05/soap-envelope/role/next"none "http://www.w3.org/2003/05/soap-envelope/role/none"

ultimateReceiver "http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver"własna http://serwer/rola

Tablica 1.1: Nazwy ról w SOAP

Składnia:

soap:actor="URI"

Przykład nagłówka z elementem actor:

<?xml version="1.0"?><soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"><soap:Header>

<m:Transxmlns:m="http://www.w3schools.com/transaction/"

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 14

soap:actor="http://www.w3schools.com/appml/">234

</m:Trans></soap:Header>......

</soap:Envelope>

Atrybut mustUnderstand (opcjonalny) okresla, czy element w którym go uzyto jest obowiazkowy czyopcjonalny do przetworzenia. Jesli atrybut jest ustawiony, a odbiorca nie zrozumie uzytego elementu,zostanie przerwane przetwarzanie i zwrócony zostanie bład.

Przykładowy komunikat wraz z nagłówkiem wyglada nastepujaco:

<?xml version="1.0"?><soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header><m:Trans

xmlns:m="http://www.w3schools.com/transaction/"soap:mustUnderstand="1">234</m:Trans>

</soap:Header>......

</soap:Envelope>

zapis m:Trans oznacza metode Trans obiektu m. Składnia:

soap:mustUnderstand="0|1"

Atrybut encodingStyle (opcjonalny): wyjasniony w punkcie 1.3.2.1

1.3.2.3 Ciało (body)

Element obowiazkowy.Ciało komunikatu zawiera wszystkie informacje, które koncowy odbiorca powinien otrzymac. Jego

przetwarzanie moze byc uwarunkowane za pomoca nagłówka. Przykład ciała komunikatu:

<?xml version="1.0"?><soap:Envelopexmlns:soap="http://www.w3.org/2001/12/soap-envelope"soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"><soap:Body>

<m:PobierzeCene xmlns:m="http://www.w3schools.com/ceny"><m:Nazwa>Jablko</m:Nazwa>

</m:PobierzCene></soap:Body></soap:Envelope>

Odpowiedz na ten komunikat powinna wygladac nastepujaco:

<?xml version="1.0"?><soap:Envelopexmlns:soap="http://www.w3.org/2001/12/soap-envelope"soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"><soap:Body>

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 15

Element Opis<faultcode> kod identyfikujacy bład<faultstring> opis błedu<faultactor> informacja o wezle który spowodował bład

<detail> szczegóły błedu

Tablica 1.3: Elementy komunikatu fault

<m:PobierzCeneOdpowiedz xmlns:m="http://www.w3schools.com/ceny"><m:Cena>1.90</m:Cena>

</m:PobierzCeneOdpowiedz></soap:Body></soap:Envelope>

1.3.2.4 Bład (fault)

Element opcjonalny.Ta czesc komunikatu zawiera opis ewentualnych błedów. Jest potomkiem elementu Body, nie Enve-

lope.Komunikat błedu wyglada nastepujaco:

<soapenv:Envelope><soapenv:Body>

<soapenv:Fault><faultcode>ns1:Client</faultcode><faultstring>Wykonano niepoprawna operacje</faultstring><detail>

<ns2:hostname>webservices</ns2:hostname></detail>

</soapenv:Fault></soapenv:Body></soapenv:Envelope>

1.3.3 Przykładowa para komunikatówZobaczmy teraz przykładowa pare komunikatów SOAP. Klient wysyła argument

<host xsi:type="xsd:string">gdzie host to nazwa argumentu, xsi:type to atrybut typu String o wartosci inotel.pl do funkcji getIP().

W zamian oczekuje czegos bardziej skomplikowanego: struktury Adres, która składa sie z nazwy zadanegohosta i jego adresu IP (obliczony na serwerze). Komunikat klienta wyglada nastepujaco:

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope

xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:ns1="http://serwer"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body>

<ns1:getIP><host xsi:type="xsd:string">

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 16

inotel.pl</host>

</ns1:getIP></SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Czescia przenoszaca dane jest <SOAP-ENV:Body>. Metoda która wywołujemy to getIP (<ns1:getIP>).Widac tam argument host typu String (<host xsi:type="xsd:string">) i wartosci inotel.pl. Serwer odpowiada:

<?xml version="1.0"encoding="UTF-8"?><SOAP-ENV:Envelope

xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:ns1="http://serwer"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body>

<ns1:getIPResponse><getIPReturn xsi:type="SOAP-ENC:Struct">

<nazwa xsi:type="xsd:string">inotel.pl

</nazwa><adres xsi:type="xsd:string">

193.109.91.135</adres>

</getIPReturn></ns1:getIPResponse>

</SOAP-ENV:Body></SOAP-ENV:Envelope>

Tutaj równiez informacja zawarta jest w czesci <SOAP-ENV:Body>. Dostajemy strukture składajaca sie znazwy i adresu IP, czyli to czego oczekiwalismy.

Jak widac znajac XML, mozna z łatwoscia odczytac (przynajmniej podstawowe) komunikaty SOAP.

1.4 Format WSDLWSDL (Web Services Description Language, http://www.w3.org/TR/wsdl)

jest dokumentem XML(6.1.1) opisujacym udostepnione przez serwer Web Services. Udostepniajacliste dostepnych metod, ich argumenty (w tym złozone typy danych) i zwracane typy, w prosty sposóbdefiniuje schemat komunikacji na linii klient-serwer. Dzieki rozszerzalnosci WSDL pozwala opisywacprocedury i ich formaty niezaleznie od protokołów uzytych do przekazywania danych. W chwili obecnejwiekszosc aplikacji oferuje automatyczne generowanie pliku WSDL, jednak przydatnosc jego odczytaniajest bardzo pomocna.

1.4.1 Przykładowy listing WSDLSpróbujmy odczytac przykładowy plik WSDL. Cały listing niepoprzerywany komentarzami znajduje siew punkcie 2.5.1.2.

<?xml version="1.0" encoding="UTF-8"?>

Okreslenie wersji standardu XML (1.0) i kodowania znaków dokumentu (utf8).

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 17

<wsdl:definitionstargetNamespace="http://localhost:8080/axis/test/HelloWorld.jws"xmlns:apachesoap="http://xml.apache.org/xml-soap"xmlns:impl="http://localhost:8080/axis/test/HelloWorld.jws"xmlns:intf="http://localhost:8080/axis/test/HelloWorld.jws"xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"xmlns:xsd="http://www.w3.org/2001/XMLSchema">

Powyzszy fragment to zdefiniowanie podstawowych informacji na temat samego dokumentu, a takzeprzestrzeni nazw w jakiej znajduja sie zmienne i metody wymienione dalej.

<!--WSDL created by Apache Axis version: 1.2.1Built on Jun 14, 2005 (09:15:57 EDT)-->

Komentarz generatora.

<wsdl:message name="getIPRequest"><wsdl:part name="host" type="xsd:string"/>

</wsdl:message><wsdl:message name="getIPResponse">

<wsdl:part name="getIPReturn" type="xsd:string"/></wsdl:message>

Sa to opisy dwóch komunikatów: getIPRequest i getIPResponse. Pierwszy z komunikatów słuzy dowywołania metody getIP, a drugi definiuje odpowiedz tej metody. Nazwy które sie tu pojawiaja, nie saobowiazkowe. Powiazanie komunikatu z metoda widac w dalszej czesci dokumentu.

Kazdy z tagów opisujacych komunikat zawiera okreslenie zwiazanych z nim danych. W przypadkugetIPRequest jest to String o nazwie host. Łaczac sie z serwerem, klient wysyła dokument SOAP, wktórym podana jest własnie nazwa tego komunikatu, a takze argument o tej nazwie. Klient dowiaduje sie ojej istnieniu własnie z pliku WSDL. W przypadku getIPResponse odczytujemy, ze po wykonaniu metodygetIP serwer odesle nam komunikat z łancuchem znaków.

Mozliwe jest równiez stosowanie złozonych typów danych. Korzysta sie wtedy z dodatkowych definicjitypów.

<wsdl:message name="helloResponse"><wsdl:part name="helloReturn" type="xsd:string"/>

</wsdl:message><wsdl:message name="helloRequest"></wsdl:message>

Tutaj widzimy prosta metode nie przyjmujaca parametrów. Zwrócmy uwage, ze kolejnosc definiowaniakomunikatów nie jest wazna w obrebie nadrzednego tagu.

<wsdl:message name="podzielResponse"><wsdl:part name="podzielReturn" type="xsd:float"/>

</wsdl:message><wsdl:message name="podzielRequest">

<wsdl:part name="a" type="xsd:int"/><wsdl:part name="b" type="xsd:int"/>

</wsdl:message>

Metoda podzielRequest przyjmuje dwa parametry typu int, zwraca jeden float.

<wsdl:portType name="HelloWorld">

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 18

Port type to nazwany zbiór abstrakcyjnych operacji i powiazanych z nimi abstrakcyjnych komunikatów.Nazwa portu jest unikalna w obrebie dokumentu.

<wsdl:operation name="getIP"parameterOrder="host"><wsdl:input message="impl:getIPRequest" name="getIPRequest"/><wsdl:output message="impl:getIPResponse" name="getIPResponse"/>

</wsdl:operation>

Tutaj pojawia sie wspomniane wyzej powiazanie komunikatów z metodami. Widac wyrazne zaznaczenie,jak nazywa sie metoda która wywołujemy, jej parametry oraz który komunikat jest wejsciowy, a którywyjsciowy.

<wsdl:operation name="hello"><wsdl:input message="impl:helloRequest" name="helloRequest"/><wsdl:output message="impl:helloResponse" name="helloResponse"/>

</wsdl:operation><wsdl:operation name="podziel" parameterOrder="a b">

<wsdl:input message="impl:podzielRequest" name="podzielRequest"/><wsdl:output message="impl:podzielResponse" name="podzielResponse"/>

</wsdl:operation></wsdl:portType><wsdl:binding name="HelloWorldSoapBinding" type="impl:HelloWorld">

Ta czesc opisuje szczegółowo sposób łaczenia metod zdefiniowanych wyzej z własciwym serwisem.

<wsdlsoap:binding style="rpc"transport="http://schemas.xmlsoap.org/soap/http"/>

Okreslony zostaje styl wymiany komunikatów na RPC (remote procedure call, zdalne wywołanie proce-dury). Styl ten polega na tym, ze komunikacja odbywa sie na zasadzie wysłania pojedynczej procedury dowykonania i otrzymanie odpowiedzi. Innym, bardziej rozbudowanym, sposobem jest document orientedcommunication, gdzie zakłada sie wykonanie całego przesłanego dokumentu XML, opisujacego kolejnemetody do wywołania.

<wsdl:operation name="getIP"><wsdlsoap:operation soapAction=""/><wsdl:input name="getIPRequest">

<wsdlsoap:bodyencodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://DefaultNamespace" use="encoded"/>

</wsdl:input><wsdl:output

name="getIPResponse"><wsdlsoap:body

encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://localhost:8080/axis/test/HelloWorld.jws"

use="encoded"/></wsdl:output>

</wsdl:operation>

Tutaj znajduja sie wiadomosci na temat rodzajów komunikatów i standardów według których maja bycbudowane.

<wsdl:operation name="hello"><wsdlsoap:operation soapAction=""/>

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 19

<wsdl:input name="helloRequest"><wsdlsoap:body

encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://DefaultNamespace"use="encoded"/>

</wsdl:input><wsdl:output

name="helloResponse"><wsdlsoap:body

encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://localhost:8080/axis/test/HelloWorld.jws"use="encoded"/>

</wsdl:output></wsdl:operation><wsdl:operation name="podziel">

<wsdlsoap:operation soapAction=""/><wsdl:input name="podzielRequest">

<wsdlsoap:bodyencodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://DefaultNamespace"use="encoded"/>

</wsdl:input><wsdl:output name="podzielResponse">

<wsdlsoap:bodyencodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://localhost:8080/axis/test/HelloWorld.jws"use="encoded"/>

</wsdl:output></wsdl:operation>

</wsdl:binding>

<wsdl:servicename="HelloWorldService"><wsdl:port binding="impl:HelloWorldSoapBinding" name="HelloWorld">

<wsdlsoap:addresslocation="http://localhost:8080/axis/test/HelloWorld.jws"/>

</wsdl:port></wsdl:service>

Korzystajac z wyzej zdefiniowanych elementów, mozemy stworzyc ostatni, najwazniejszy fragment WSDL.Z tagu <wsdl:service> klient dowiaduje sie wszystkiego o serwisie, czyli adres pod który ma kierowac za-pytania (adres serwera) i jak ma je budowac.

</wsdl:definitions>

Jak widac, dokument WSDL jest po prostu zbiorem definicji metod i danych zapisanym w jezyku pochod-nym od XMLa.

1.5 UDDIUDDI, Universal Description, Discovery, and Integration (uniwersalny opis, odkrywanie i scalanie)

UDDI jest niezaleznym od platformy, opartym o jezyk XML (6.1.1) rejestrem umozliwiajacym odna-jdywanie i scalanie aplikacji biznesowych z całego swiata poprzez internet. Kazdy moze dodac swojausługe do katalogu, tak by inni mogli ja odnalezc, lub tez skorzystac z juz zamieszczenych roziwaznan.

ROZDZIAŁ 1. WEB SERVICES - TWORZENIE I UZYTKOWANIE 20

UDDI jest otwartym standardem opracowywanym przez OASIS, która wprowadziła nastepujace okresle-nia:

• White Pages (białe strony) - dane pozwalajace na kontakt ze zgłoszona firma ( addres, email itp)

• Yellow Pages (zólte strony) - spis usług pogrupowanych według standardowy kategorii

• Green Pages (zielone strony) - szczegóły techniczne udostepnionych usług

UDDI jest jednym z głównych skladników standardów Web Services. Zoststał stworzony by mógl pow-stac system szybkiego i bezpiecznego wyszukiwania i wykorzystania Web Services właczonych do kata-logu przez innych uzytkowników. W kazdyms erwisie udostepniony jest dokument WSDL (1.4) opisujacymetody łaczenia i format komunikatów wymagany do współpracy z danym Web Service.

UDDI korzysta ze stworzonych przez WorldWide Web Consortium (W3C) i Internet Engineering TaskForce (IETF) narzedzi: jezyka XML, HTTP i DNS. Dodatkowo, uzywane sa tez miedzyplatformowemetody programowania przy wykorzystaniu jezyka Simple Object Access Protocol (SOAP).

Rozdział 2

Web Services z wykorzystaniem ApacheAxis

2.1 Co to jest AxisApache Axis (http://ws.apache.org) jest implementacja protokołu SOAP ("Simple Object AccessProtocol", 1.3), stworzona według standardów W3C. Dokładniej mówiac, jest to silnik, który zapewniazarówno łatwe udostepnienie, jak i korzystanie z udostepnionych przez innych Web Services. Podstawowawersja Axis napisana jest w Javie, ale powstaje równiez odmiana w C++ (Axis C++ http://ws.apache.org/axis/cpp/index.html).Apache Axis jest projektem Open Source, udostepnianym na podstawie licencji Apache http://ws.apache.org/LICENSE.txt .

2.2 InstalacjaZainstalujemy najpierw wymagane oprogramowanie, nastepnie samego Axisa.

2.2.1 Wymagane oprogramowanie• Java

Wymagane jest srodowisko Java. Tutaj uzyto SUN Java 2 Platform Standard Edition DevelopmentKit 5.0 update 4, dostepne pod adresem http://java.sun.com/j2se/1.5.0/download.jsp .

• Serwer (web container)

Apache Axis nie jest samodzielna aplikacja. Do działania potrzebuje zewnetrznego serwera. Natu-ralnym wyborem wydaje sie byc darmowy serwer dostepny równiez w ramach organizacji Apache:Jakarta Tomcat (Jakarta Tomcat http://jakarta.apache.org/tomcat/). W tym tutorialu uzytoTomcata w wersji 5.5, nasłuchujacego na porcie 8080 (standardowy port Tomcata). Mozliwe jestrówniez uzycie innego serwera, który powinien zachowywac sie w miare podobnie jak Tomcat.

2.2.2 Pobranie AxisaAxis moze zostac pobrany w dwóch postaciach: kodu zródłowego do samodzielnej kompilacji (source) igotowego pakietu (binary). Skorzystamy z drugiej opcji. Ze strony http://ws.apache.org/axis/releases.htmlpobierzmy najswiezsza wersje. Nalezy wybrac najblizej geograficznie połozony serwer lustrzany (mirror),zazwyczaj jest on sugerowany przez strone. Z serwera sciagamy najnowsza wersje Axis, tutaj została uzytawersja 1.2.1 z 15 czerwca 2005. Adres: http://www.apache.net.pl/ws/axis/1_2_1/axis-bin-1_2_1.tar.gzlub http://www.apache.net.pl/ws/axis/1_2_1/axis-bin-1_2_1.zip .

Otrzymamy paczke, która nalezy rozpakowac do katalogu axis. Jej zawartosc to:

• docs - dokumentacja

21

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 22

• lib - biblioteki wykorzystywane przez axis

• samples - przykładowe programy

• webapps - katalog zawierajacy jadro Axis

• xmls - pliki XML

• pliki LICENCE, README, release-notes.html - opis Axis

2.2.3 Instalacja pakietuW katalogu serwera (np. /usr/local/tomcat/ ), powinien znajdowac sie podkatalog zawierajacy aplikacjeinternetowe (”webapps”). Do niego nalezy skopiowac katalog webapps/axis znajdujacy sie w miejscu,do którego rozpakowalismy Axisa. Konieczne sa do tego uprawnienia administratora (o ile wczesniej niezostały zmienione prawa do katalogu webapps). Czyli nalezy skopiowac axis-1_2_1/webapps/axis/ dokatalogu /usr/local/tomcat/webapps/

2.2.3.1 Opcjonalna instalacja parsera XML

Axis potrzebuje do działania parsera XML. Jezeli serwer nie udostepnia na zewnatrz zadnego, potrzebnabedzie jego instalacja. Java w wersji 1.4 zawiera parser Crimson, który moze byc wykorzystany, chociazpreferowany jest Xerces http://xml.apache.org/dist/xerces-j/ , który jest zawarty w Javie 5 lubdostepny jako samodzielna biblioteka.

Jezeli wiec na komputerze zainstalowana jest Java 1.4 lub nowsza, mozna pominac ten punkt.Aby dodac parser XML, wybierz parser zgodny z JAXP 1.1 XML. O ile serwer nie ma swoich indy-

widualnych ustawien, instalacja polega na przegraniu biblioteki do katalogu axis/WEB-INF/lib, a nastepniedodac do AXISCLASSPATH sciezki do xml-apis.jar i xercesImpl.jar (w przypadku xerces). Wynikiemnieprawidłowej instalacji parsera sa błedy zwiazane z CLASSPATH lub AXISCLASSPATH.

2.2.3.2 Uzycie Axis 1.2 razem z WebLogic 8.1

Biblioteka webservices.jar zawarta w WebLogic 8.1 powoduje konflikt ze standardowa biblioteka Axissaaj.jar. Dzieje sie tak z powodu uzywania przez WebLogic starszej definicji pakietu javax.xml.soap.* zJava Web Services Developer Pack Version 1.0, podczas gdy Axis uzywa nowszej wersji z J2EE 1.4.

Sa jednak mozliwe zmiany w konfiguracji pozwalajace na uruchomienie. Szczegóły na stronie http://ws.apache.org/axis/java/install.html#WebLogic8.1 .

2.2.4 Ustawienie zmiennych systemowychUstawianie podanych tutaj zmiennych jest konieczne, jesli zamierzamy kompilowac lub uruchamiac WebServices z linii polecen. W przeciwnym przypadku mozna ominac ten punkt.

Zmienne w systemie Unixowym nalezy wpisac do odpowiedniego pliku w katalogu /etc (np. /etc/enviroment)lub do pliku uzytkownika (np. .bashrc). W Windowsie nalezy kliknac prawym przyciskiem myszy naikonie “Mój komputer”, wybrac “Własciwosci”, zakładka “Zaawansowane”

Zmienna Przykładowa sciezka Linux Przykładowa sciezka WindowsJAVA_HOME /usr/local/lib/jdk1.5.0_04/ c:\sun\jdk

CATALINA_HOME /usr/local/tomcat5 c:\apache\tomcat5\AXIS_HOME $CATALINA_HOME/axis %CATALINA_HOME%\axis

AXIS_LIB $AXIS_HOME/lib %AXIS_HOME%\libAXISCLASSPATH patrz nizej patrz nizej

Tablica 2.1: Zmienne systemowe

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 23

Konieczne jest równiez ustawienia sciezki AXISCLASSPATH, aby wskazywała na potrzebne bib-lioteki. Wszystkie nowe biblioteki dodawane do projektów, nalezy równiez wpisac do tej zmiennej. Listapoczatkowo potrzebnych bibliotek:

• Unix

AXIS_HOME=/usr/axisAXIS_LIB=$AXIS_HOME/libAXISCLASSPATH=$AXIS_LIB/axis.jar:$AXISCLASSPATHAXISCLASSPATH=$AXIS_LIB/commons-discovery.jar:$AXISCLASSPATHAXISCLASSPATH=$AXIS_LIB/commons-logging.jar:$AXISCLASSPATHAXISCLASSPATH=$AXIS_LIB/jaxrpc.jar:$AXISCLASSPATHAXISCLASSPATH=$AXIS_LIB/saaj.jar:$AXISCLASSPATHAXISCLASSPATH=$AXIS_LIB/log4j-1.2.8.jar:$AXISCLASSPATHAXISCLASSPATH=$AXIS_LIB/xml-apis.jar:$AXISCLASSPATHAXISCLASSPATH=$AXIS_LIB/xercesImpl.jar $AXISCLASSPATHexport AXIS_HOME; export AXIS_LIB; export AXISCLASSPATH

• Windows

set AXIS_HOME=c:\axisset AXIS_LIB=%AXIS_HOME%\libset AXISCLASSPATH=%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar;

%AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar

Przy kazdym uruchamianiu aplikacji uzywajacej AXIS nalezy wykonywac ja ze zmienna AXISCLASS-PATH.

• Unix:

java -cp "$AXISCLASSPATH" ...

• Windows

java -cp %AXISCLASSPATH ...

Nie bedzie to konieczne jesli dodamy zmienna AXISCLASSPATH do CLASSPATH:

• Unix

set CLASSPATH=AXISCLASSPATH:$CLASSPATH

• Windows

set CLASSPATH=%AXISCLASSPATH%;%CLASSPATH%

2.2.5 Sprawdzenie instalacjiJezeli wszystko poszło dobrze, pod adresem http://localhost:8080/axis/happyaxis.jsp lub http://127.0.0.1:8080/axis/happyaxis.jsppowinna byc dostepna “Strona Szczesliwosci Axis” (“Axis Happiness Page”), podsumowujaca instalacje.

Znajduje sie tam spis wymaganych oraz opcjonalnych bibliotek. Jezeli wszystkie wymagane sa zain-stalowane (“The core axis libraries are present.”) , mozna juz korzystac z Axisa.

Jezeli jednak brak którejs z bibliotek, nalezy ja odnalezc i zainstalowac. Najłatwiejszym sposobemjest skorzystanie z wyszukiwarki Jarhoo http://www.jarhoo.com/j. Nalezy tam zaznaczyc opcje JarFile i podac nazwe biblioteki której szukamy. Pojawi sie lista pakietów zawierajacych dana biblioteke, jakrówniez domyslne połozenie biblioteki wewnatrz pakietu. Odnaleziony plik nalezy przegrac do kataloguaxis/WEB-INF/lib.

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 24

2.3 Struktura katalogówStruktura katalogu axis wewnatrz katalogu webapps:

axis/WEB-INF/classes/lib/users.lstweb.xml

Plik users.listKatalog WEB-INF zawiera wiadomosci konfiguracyjne, ale moze zostac równiez uzyty do przechowywa-

nia zaleznosci i serwisów które zamierzamy udostepnic.Katalog classes zawiera skompilowane klasy których uzywa Axis. Znajduja sie tam równiez skompi-

lowany przykłady.Katalog lib zawiera biblioteki potrzebne do działania Axis i Web Services, jak równiez moze prze-

chowywac gotowe aplikacje uzytkownika (spakowane do pliku .jar).Plik users.lst jest wykorzystywany jesli uzytkownik korzysta z systemów zabezpieczen w bibliotece

xml-axis (nie zalecane).Plik web.xml zawiera ustawienia Axis.

2.4 Korzystanie z Axis

2.4.1 Lista uruchomionych serwisówListe aktualnie dostepnych za pomoca Axis serwisów mozna obejrzec pod adresem http://localhost:8080/axis/servlet/AxisServlet ,standardowo sa to AdminService, oraz Version. Nie sa tu widoczne serwisy opublikowane za pomocaplików .jws (opis: 2.4.2.1).

Rysunek 2.1: Lista Web Services dostepnych w Axis

Konstrukcja listy wyglada nastepujaco:

• NazwaSerwisu (linkDoWsdl)

• funkcja1

• funkcja2

• ....

Wynikiem klikniecia na link do pliku WSDL bedzie dokument XML wygenerowany automatycznie przezAxis. Mamy równiez mozliwosc wywołania metody getVersion bezposrednio za pomoca adresu http://localhost:8080/axis/services/Version?method=getVersion .Wynikiem powinno byc

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 25

<soapenv:Envelope><soapenv:Body>

<getVersionResponsesoapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getVersionReturn xsi:type="xsd:string">

Apache Axis version: 1.2.1 Built on Jun 14, 2005 (09:15:57 EDT)</getVersionReturn>

</getVersionResponse></soapenv:Body>

</soapenv:Envelope>

Wersja moze sie oczywiscie róznic.

2.4.2 Dodawanie własnych serwisówGłównym celem Axis jest własnie umozliwianie udostepniania Web Services. Sa na to dwie metody.

2.4.2.1 Udostepnianie Web Services za pomoca plików JWS

Jest to prostsza z dwóch metod, która nadaje sie do szybkiego udostepnienia serwisu, jednak ze wzgledu naliczne ograniczenia, a raczej brak mozliwosci konfiguracji, nadaje sie własciwie tylko do celów testowych.

Zeby skorzystac z tego sposobu, wystarczy stworzyc klase w Javie, zmienic rozszerzenie pliku jazwierajacego na .jws, a nastepnie przegrac ten plik do katalogu axis (katalog jest w zasadzie dowolny,z wyjatkiem WEB-INF, nalezy tylko pamietac o podaniu w przegladarce dobrej sciezki).

2.4.2.2 Rozbudowana metoda udostepniania Web Services

Druga metoda jest bardziej skomplikowana, ale pozwala na osiagniecie wymaganych rezultatów. Polegana napisaniu klas (najlepiej zebranych w pakiet), a nastepnie dołaczenie ich do Axisa.

Nalezy wgrac skompilowane klasy, które zamierzamy zainstalowac do katalogu $AXIS_HOME/WEB-INF/classes. Nalezy pamietac o zachowaniu struktury pakietu. Jezeli klasy sa umieszczone w pliku .jar,nalezy wgrac je do katalogu $AXIS_HOME/WEB-INF/lib. do tego katalogu nalezy równiez dograc wszys-tkie biblioteki, z których korzysta nowy serwis.

Po dodaniu nowych klas lub bibliotek nalezy uzyc mechanizmu serwera pozwalajacego na odswiezenieaplikacji, lub jesli takiego mechanizmu nie ma, zrestartowac serwer,

Po dodaniu i restarcie, nowy serwis powinien byc widoczny pod adresem http://localhost:8080/axis/servlet/AxisServlet .

2.5 Pisanie aplikacji serwera z wykorzystaniem AxisAxis oferuje zbiór bibliotek i mechanizmów umozliwiajacych w miare proste tworzenie i udostepnianieWeb Services. Opisze tutaj szczegółowo jak stworzyc, skompilowac i udostepnic aplikacje. Poznamy dwasposoby tworzenia aplikacji: za pomoca pliku .JWS (2.5.1) a takze druga, bardziej rozbudowana (2.5.2).

2.5.1 Uzycie plików .JWS2.5.1.1 Tworzenie kodu zródłowego

Pierwszym krokiem jest decyzja, co własciwie chcemy zrobic. Tutaj stworzymy serwis, który bedzieposiadał nastepujaca funkcjonalnosc:

• wypisze “Hello World”

• podzieli przez siebie dwie liczby dane w parametrze (przyjmuje dwa argumenty (int) i zwraca wynikdzielenia (float))

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 26

• i bardziej zaawansowana cecha: zamieni podana w parametrze nazwe hosta (String) na adres IP(String)

Wszystkie metody wykonujace funkcje, które maja byc dostepne na zewnatrz, musza byc zadeklarowanejako metody publiczne. Dodamy jeszcze jedna metode: private niedostepna(), której próba wywołaniazakonczy sie błedem. Kod klasy opisuje algorytm

import java.net.InetAddress;public class HelloWorld{

public String hello(){System.out.println("Tego nie bedzie widac");return "Hello World!";

}private String niedostepna(){

System.out.println("metody private nie da sie wywolac");return "halo";

}public float podziel(int a, int b){

return (float)a/b;}public String getIP(String host){

try{java.net.InetAddress inetAdd =

java.net.InetAddress.getByName(host);return inetAdd.getHostAddress();

}catch(java.net.UnknownHostException uhe){

return "Host " + host + " nie zostal znaleziony";}

}}

2.5.1.2 Udostepnianie klasy

Plik HelloWorld.java przegrywamy do katalogu $AXIS_HOME/test/ zmieniajac jej nazwe na HelloWorld.jws.Kompilacja metody zajmie sie Axis. Wazne jest, aby miec równiez prawo zapisu do katalogu $AXIS_HOME/WEB-INF/jwsClasses, poniewaz tam zostanie utworzona skompilowana wersja naszej klasy. Jezeli wszystkoposzło dobrze, pod adresem http://localhost:8080/axis/test/HelloWorld.jws powinnismy zobaczyckomunikat “There is a Web Service here”, a pod adresem http://localhost:8080/axis/test/HelloWorld.jws?wsdldynamicznie wygenerowany plik WSDL:

<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions

targetNamespace="http://localhost:8080/axis/test/HelloWorld.jws"xmlns:apachesoap="http://xml.apache.org/xml-soap"xmlns:impl="http://localhost:8080/axis/test/HelloWorld.jws"xmlns:intf="http://localhost:8080/axis/test/HelloWorld.jws"xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"xmlns:xsd="http://www.w3.org/2001/XMLSchema"><!--WSDL created by Apache Axis version: 1.2.1

Built on Jun 14, 2005 (09:15:57 EDT)--><wsdl:message name="getIPRequest">

<wsdl:part name="host" type="xsd:string"/>

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 27

</wsdl:message><wsdl:message name="getIPResponse">

<wsdl:part name="getIPReturn" type="xsd:string"/></wsdl:message><wsdl:message name="helloResponse">

<wsdl:part name="helloReturn" type="xsd:string"/></wsdl:message><wsdl:message name="helloRequest"></wsdl:message><wsdl:message name="podzielResponse">

<wsdl:part name="podzielReturn" type="xsd:float"/></wsdl:message><wsdl:message name="podzielRequest">

<wsdl:part name="a" type="xsd:int"/><wsdl:part name="b" type="xsd:int"/>

</wsdl:message><wsdl:portType name="HelloWorld">

<wsdl:operation name="getIP"parameterOrder="host"><wsdl:input message="impl:getIPRequest" name="getIPRequest"/><wsdl:output message="impl:getIPResponse" name="getIPResponse"/>

</wsdl:operation><wsdl:operation name="hello">

<wsdl:input message="impl:helloRequest" name="helloRequest"/><wsdl:output message="impl:helloResponse" name="helloResponse"/>

</wsdl:operation><wsdl:operation name="podziel" parameterOrder="a b">

<wsdl:input message="impl:podzielRequest" name="podzielRequest"/><wsdl:output message="impl:podzielResponse" name="podzielResponse"/>

</wsdl:operation></wsdl:portType><wsdl:binding name="HelloWorldSoapBinding" type="impl:HelloWorld">

<wsdlsoap:binding style="rpc"transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="getIP"><wsdlsoap:operation soapAction=""/><wsdl:input name="getIPRequest">

<wsdlsoap:bodyencodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://DefaultNamespace" use="encoded"/>

</wsdl:input><wsdl:output

name="getIPResponse"><wsdlsoap:body

encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://localhost:8080/axis/test/HelloWorld.jws"

use="encoded"/></wsdl:output>

</wsdl:operation><wsdl:operation name="hello">

<wsdlsoap:operation soapAction=""/><wsdl:input name="helloRequest">

<wsdlsoap:bodyencodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 28

namespace="http://DefaultNamespace"use="encoded"/>

</wsdl:input><wsdl:output

name="helloResponse"><wsdlsoap:body

encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://localhost:8080/axis/test/HelloWorld.jws"use="encoded"/>

</wsdl:output></wsdl:operation><wsdl:operation name="podziel">

<wsdlsoap:operation soapAction=""/><wsdl:input name="podzielRequest">

<wsdlsoap:bodyencodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://DefaultNamespace"use="encoded"/>

</wsdl:input><wsdl:output name="podzielResponse">

<wsdlsoap:bodyencodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://localhost:8080/axis/test/HelloWorld.jws"use="encoded"/>

</wsdl:output></wsdl:operation>

</wsdl:binding><wsdl:service

name="HelloWorldService"><wsdl:port binding="impl:HelloWorldSoapBinding" name="HelloWorld">

<wsdlsoap:addresslocation="http://localhost:8080/axis/test/HelloWorld.jws"/>

</wsdl:port></wsdl:service>

</wsdl:definitions>

Ten dokument został objasniony w punkcie opisujacym format WSDL(1.4).

2.5.1.3 Łaczenie sie z Web Service za pomoca URL

Wystarczy teraz połaczyc sie z Web Service’m. Mozna to zrobic na kilka sposobów - najlepszym jestskorzystanie z zewnetrznego klienta (opisane w rozdziale 2.6). Jednak narazie, skoro nie wiemy jeszczejak go napisac, posłuzymy sie prymitywna metoda i skorzystamy z wywołan za pomoca URL. Jest tometoda ograniczona, stojaca w zasadzie w sprzecznosci z idea Web Services, jednak wystarczy ona dlanaszych prostych celów edukacyjnych.

Wywołanie za pomoca URL polega na wpisaniu odpowiednio sformatowanego adresu.

http://localhost:8080/axis/katalogZJWS/Klasa.jws?op1=wart1&op2=wart2&op3=wart3

Interesowac beda nas w zasadzie tylko nastepujace opcje:

• ?wsdl wyswietla plik WSDL

• ?method=hello - okresla nazwe metody do wywołania (hello)

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 29

• ?method=hello&arg1=2&arg2=4 - wywołuje funkcje hello z argumentem o nazwie arg1 i wartosci2 oraz argumentem o nazwie arg2 i wartosci 4. Kolejnosc nie jest wazna, nazwy argumentów tak.Szczegóły sa opisane przy opisie metody podziel() (2.5.1.4)

2.5.1.4 Testowanie udostepnionych metod

Mamy do przetestowania cztery udostepnione metody.

Metoda hello() Metoda hello() próbuje wypisac na stdout komunikat, który nie jest widoczny dla przegla-darki (pojawi sie natomiast w logach Tomcata). Natomiast widoczna jest wartosc zwracana. Rezultatemwywołania adresu

http://localhost:8080/axis/test/HelloWorld.jws?method=hellojest

<soapenv:Envelope><soapenv:Body>

<helloResponsesoapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

<helloReturn xsi:type="xsd:string">Hello World!</helloReturn></helloResponse>

</soapenv:Body></soapenv:Envelope>

Metoda niedostepna() Metoda niedostepna() jest zadeklarowana jako private, dlatego nie jest dostepna.Odpowiedzia na wywołanie

http://localhost:8080/axis/test/HelloWorld.jws?method=niedostepnajest

<soapenv:Envelope><soapenv:Body>

<soapenv:Fault><faultcode>ns1:Client</faultcode><faultstring>No such operation ’niedostepna’</faultstring><detail>

<ns2:hostname>webservices</ns2:hostname></detail>

</soapenv:Fault></soapenv:Body></soapenv:Envelope>

Metoda podziel() Metoda podziel() jest troche trudniejsza, poniewaz przyjmuje parametry - a i b. Wystar-czy je podac w adresie

http://localhost:8080/axis/test/HelloWorld.jws?method=podziel&a=1&b=3Odpowiedz bedzie wygladała nastepujaco:

<soapenv:Envelope><soapenv:Body>

<podzielResponsesoapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><podzielReturn xsi:type="xsd:float">0.33333334</podzielReturn>

</podzielResponse></soapenv:Body>

</soapenv:Envelope>

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 30

Argumenty sa rozpoznawane po ich nazwie. Ten sam rezultat dałoby wywołaniehttp://localhost:8080/axis/test/HelloWorld.jws?method=podziel&b=3&a=1Nie podanie wymaganych argumentów skonczy sie błedem:

<soapenv:Envelope><soapenv:Body>

<soapenv:Fault><faultcode>soapenv:Server.generalException</faultcode><faultstring>

Tried to invoke method public float HelloWorld.podziel(int,int)with arguments null,null.The arguments do not match the signature.;nested exception is: java.lang.IllegalArgumentException

</faultstring><detail>

<ns1:hostname>webservices</ns1:hostname></detail>

</soapenv:Fault></soapenv:Body>

</soapenv:Envelope>

Metoda getIP() Jest to najbardziej skomplikowana metoda. Importuje ona zewnetrzna biblioteke java.net.InetAddress.Jest ona dołaczona do Javy, dlatego nie było potrzebne przegrywanie jej do katalogu $AXIS_HOME/WEB-INF/lib.

Wywołujemy metode uzywajac URLhttp://localhost:8080/axis/test/HelloWorld.jws?method=getIP&host=vercom.plOtrzymana odpowiedz zdradza nam IP serwera vercom.pl:

<soapenv:Envelope><soapenv:Body>

<getIPResponsesoapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getIPReturn xsi:type="xsd:string">

193.109.91.136</getIPReturn>

</getIPResponse></soapenv:Body>

</soapenv:Envelope>

Jak widac po wywołaniuhttp://localhost:8080/axis/test/HelloWorld.jws?method=getIP&host=nieznanyserwis potrafi równiez radzic sobie z wyjatkami:

<soapenv:Envelope><soapenv:Body>

<getIPResponsesoapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getIPReturn xsi:type="xsd:string">

Host nieznany nie zostal znaleziony</getIPReturn>

</getIPResponse></soapenv:Body>

</soapenv:Envelope>

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 31

2.5.2 Metoda zaawansowanaJak widac, do stworzenia najprostszego serwisu nie potrzebna jest własciwie zadna wiedza o Axisie -wystarczy odpowiednio skopiowac klase w javie i zmienic jej rozszerzenie. Jednak problem pojawia sie,gdy mamy bardziej rozbudowana aplikacje, składajaca sie chociazby z dwóch klas. Opisze tutaj drugametode udostepniania aplikacji. Umozliwia ona prace nawet z najbardziej skomplikowanymi projektami,składajacymi sie z wielu klas czy nawet pakietów.

2.5.2.1 Tworzenie kodu zródłowego

Stwórzmy aplikacje o metodach takich jak w punkcie 2.5.1.1. Tym razem z ta róznica, ze utworzymyosobny pakiet serwis, z podpakietami:

• interfejs - klasa bez kodu, zawierajaca tylko funkcje które chcemy udostepnic swiatu

• silnik - implementacja metoda interfejsu (i innych)

Do pakietu silnik naleza klasy:

• Adres - klasa składa sie z dwóch pół nazwa i adres. Opisuje adres hosta

• Sieciowa - z metoda getIp(String host) , zwraca Adres

• Testowa - zawiera publiczne metody: podziel() i halo()

Do pakietu interfejs nalezy klasa

• InterfejsSerwisu - klasa która udostepnia na swiat metody getIP() i hello() - nie udostepnia natomiastpublicznej metody podziel() - wybiórcze udostepnianie metod publicznych nie było mozliwe przyudostepnianiu przez plik .jws

Kod pakietu serwis pokazuja listingi

• Klasa serwis.silnik.Adres

package serwis.silnik;public class Adres{

public String nazwa;public String adres;private int tajemnica=-1;

}

• Klasa serwis.silnik.Testowa

package serwis.silnik;public class Testowa{

public String hello(){System.out.println("Tego nie bedzie widac");return "Hello World!";

}private String niedostepna(){

System.out.println("metody private nie da sie wywolac");return "halo";

}public float podziel(int a, int b){

return (float)a/b;}

}

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 32

• Klasa serwis.silnik.Sieciowa

package serwis.silnik;import java.net.InetAddress;public class Sieciowa{

public Adres getIP(String host){Adres adr = new Adres();adr.nazwa = host;java.net.InetAddress inetAdd = null;try{

inetAdd = java.net.InetAddress.getByName(host);}catch(java.net.UnknownHostException uhe){}adr.adres = inetAdd.getHostAddress();return adr;

}}

• Klasa serwis.interfejs.InterfejsSerwisu

package serwis.interfejs;import serwis.silnik.Adres;public interface InterfejsSerwisu{

public Adres getIP(String host);public String hello();

}

Kompilacja Nalezy skompilowac wszystkie klasy w pakiecie (z poziomu o jeden wyzszego niz umiejs-cowienie pakietu):

javac serwis/silnik/*.java serwis/interfejs/*.java

Jezeli pojawi sie bład

Exception in thread "main" java.lang.NoClassDefFoundError: .....

znaczy to ze nie dodalismy jakiejs biblioteki lub biezacego katalogu do CLASSPATH.

Utworzenie pliku WSDL - Java2WSDL Plik WSDL tworzony jest automatycznie za pomoca polecenia

java org.apache.axis.wsdl.Java2WSDL -o serwis.wsdl \-l"http://localhost:8080/axis/services/InterfejsSerwisu" -n "urn:Serwis" \-p"serwis.interfejs.InterfejsSerwisu" \"urn:Serwis" serwis.interfejs.InterfejsSerwisu

gdzie:

• -o serwis.wsdl - okresla nazwe pliku wyjsciowego

• -l"http://localhost:8080/axis/services/InterfejsSerwisu" - docelowy adres serwisu

• -n "urn:Serwis" - przestrzen nazw serwisu

• -p"serwis.interfejs.InterfejsSerwisu" "urn:Serwis" - okresla mapowanie miedzy przestrzenia nazw apakietem

• serwis.interfejs.InterfejsSerwisu - okresla adres interfejsu

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 33

Dokładniejsze wyjasnienie uzycia klasy Java2WSDL znajduje sie pod adresem http://ws.apache.org/axis/java/reference.html#Java2WSDLReference .W katalogu w którym sie znajdujemy, powinien pokazac sie plik serwis.wsdl. Jezeli pojawi sie bład

Exception in thread "main" java.lang.NoClassDefFoundError: org.apache.axis.wsdl.Java2WSDL

nalezy dodac do CLASSPATH biblioteke wsdl4j.jar.Niestety oryginalne nazwy argumentów funkcji zostana zmienione na in0, in1 itp. Zeby uzyskac

bardziej czytelne nazwy, nalezy edytowac plik serwis.wsdl. Tutaj załoze jednak, ze tego nie zrobiono.

Utworzenie klas z WSDL - WSDL2Java Wynikiem działania klasy Java2WSDL bedzie plik WSDL,który zawiera informacje na temat naszego (docelowego) serwisu. Z pomoca tego pliku, jestesmy w staniewygenerowac klasy, które posłuza nam do prawidłowego udostepnienia serwisu. Robimy to za pomocapolecenia

java org.apache.axis.wsdl.WSDL2Java -o . \-d Session -s -p serwis.ws serwis.wsdl

gdzie:

• -o . - pliki docelowe maja znalezc sie w biezacym katalogu

• -d Session - zakres działania naszej aplikacji (Application, Session, Request)

• -s - generowanie kodu serwera

• -p serwis.ws - pakiet w którym ma sie pojawic kod

• serwis.wsdl - nazwa pliku zródłowego

Dokładniejsze wyjasnienie uzycia klasy WSDL2Java znajduje sie pod adresem http://ws.apache.org/axis/java/reference.html#WSDL2JavaReference .Wynikiem działania powinny byc klasy:

• serwis/ws/InterfejsSerwisuSoapBindingImpl.java - implementacja kodu naszego serwisu. To jedynyz wygenerowanych plików, który nalezy recznie edytowac, łaczac go z klasa InterfejsSerwisu

• serwis/ws/InterfejsSerwisuServiceLocator.java - klasa pomaga łaczyc sie z serwisem na danym por-cie

• serwis/ws/InterfejsSerwisuSoapBindingStub.java - czesc kodu potrzebna do łaczenia sie klienta

• serwis/ws/Adres.java - klasa odpowiadajaca naszemu złozonemu typowi, kazdy typ ma swoja

• serwis/ws/InterfejsSerwisuService.java - interfejs

• serwis/ws/InterfejsSerwisu_PortType.java - interfejs

• deploy.wsdd - umozliwia udostepnianie serwisu (patrz 2.5.2.2)

• undeploy.wsdd - umozliwia usuniecie udostepnionego serwisu z serwera

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 34

Modyfikacja utworzonych plików Niestety o odpowiednie połaczenie serwis.ws z pozostałymi paki-etami musimy zadbac sami. Zrobimy to edytujac plik serwis/ws/InterfejsSerwisuSoapBindingImpl.java.W pierwotnym listingu widac szkielet klasy z metodami, które zdecydowalismy sie udostepnic. Nie matam metody podziel(), która pominelismy w pliku InterfejsSieciowa.java. Czyli w odróznieniu od plików.jws mamy pełna kontrole nad udostepniana trescia. Kody klasy prezentuja sie nastepujaco:

• Oryginalny serwis.ws.InterfejsSerwisuSoapBindingImpl.java

/**** InterfejsSerwisuSoapBindingImpl.java** This file was auto-generated from WSDL* by the Apache Axis 1.2.1 Jun 14, 2005 (09:15:57 EDT) WSDL2Java emitter.*/package serwis.ws;public class InterfejsSerwisuSoapBindingImpl

implements serwis.ws.InterfejsSerwisu_PortType{public serwis.ws.Adres getIP(java.lang.String in0)

throws java.rmi.RemoteException {return null;

}public java.lang.String hello()

throws java.rmi.RemoteException {return null;

}}

• Zmodyfikowany serwis.ws.InterfejsSerwisuSoapBindingImpl.java

/*** InterfejsSerwisuSoapBindingImpl.java** This file was auto-generated from WSDL* by the Apache Axis 1.2.1 Jun 14, 2005 (09:15:57 EDT) WSDL2Java emitter.*/package serwis.ws;import serwis.silnik.Sieciowa;import serwis.silnik.Testowa;public class InterfejsSerwisuSoapBindingImpl

implements serwis.ws.InterfejsSerwisu_PortType{public serwis.ws.Adres getIP(java.lang.String in0)

throws java.rmi.RemoteException {Sieciowa s = new Sieciowa();serwis.ws.Adres swa = new serwis.ws.Adres();serwis.silnik.Adres ssa = new serwis.silnik.Adres();ssa = s.getIP(in0);swa.setNazwa(ssa.nazwa);swa.setAdres(ssa.adres);return swa;

}public java.lang.String hello()

throws java.rmi.RemoteException {Testowa t = new Testowa();return t.hello();

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 35

}}

W przypadku metody hello(), modyfikacja dotyczyła tylko stworzenia instancji klasy Testowa i odpaleniejej metody.

W przypadku metody getIP() sprawa stała sie bardziej skomplikowana za sprawa typu złozonegozwracanego przez ta klase. WSDL2Java utworzyła nowa klase serwis.ws.Adres, która jest zwracana zmetody serwis.ws.InterfejsSerwisuSoapBindingImpl.java. Nie mozna dokonac prostego rzutowania, dlat-ego tworzone sa obiekty obu klas Adres i dane sa przepisywane z tej oryginalnej do tej z pakietu serwis.ws.Reszta kodu to stworzenie i wywołanie metody getIP() analogicznie do helo().

Kompilacja nowych klas KompilacjaNalezy skompilowac nowe klasy w pakiecie (z poziomu o jeden wyzszego niz umiejscowienie pakietu):

javac serwis/ws/*.java

Tworzenie archiwum .jar Jezeli wszystko poszło dobrze, pakiet powinien byc juz dostepny w postaciplików *.class. Teraz nalezy je zebrac w archiwum.

Komenda, która stworzy pakiet jest:

jar cvf libserwis.jar serwis/ws/*.class serwis/interfejs/*.class \serwis/silnik/*.class

Wynikiem bedzie plik libserwis.jar, który nalezy skopiowac do katalogu $AXIS_HOME/WEB-INF/lib.

2.5.2.2 Udostepnianie serwisu

Kolejnym krokiem jest dodanie wpisu dotyczacego naszego serwisu do Axisa. Wpis zostanie dodawanydo pliku server-config.wsdd, który znajduje sie w katalogu $AXIS_HOME/WEB-INF. Jezeli go tam nie ma,nalezy koniecznie utworzyc nowy i nadac mu odpowiednie uprawnienia. Jezeli tego nie zrobimy, naszserwis nie pojawi sie w Axisie.

Komenda dopisujaca nasz serwis do pliku server-config.wsdd jest:

java org.apache.axis.client.AdminClient serwis/ws/deploy.wsdd

Odpowiedzia powinno byc

<admin>Done processing</admin>

W tym momencie nasz serwis powinien byc juz widoczny na liscie http://localhost:8080/axis/servlet/AxisServlet .Jezeli tak sie nie stało, nalezy sprawdzic czy wpis o naszym serwisie pojawił sie w pliku server-config.wsdd.Jezeli nie, trzeba zmienic prawa zapisu do pliku i spróbowac ponownie udostepniania. Jezeli plik zawierawpisy, mozna spróbowac zrestartowac serwer.

Jezeli bedziemy chcieli kiedys usunac nasz serwis, polecenie wyglada nastepujaco:

java org.apache.axis.client.AdminClient serwis/ws/undeploy.wsdd

Odpowiedzia powinno byc

<admin>Done processing</admin>

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 36

2.6 Pisanie aplikacji klienta z wykorzystaniem AxisZaleta Web Services jest to, ze pod wzgledem jezyka programowania aplikacja klienta jest całkowicieniezaleznie od serwera. W tym artykule, stworzylismy klienta od podstaw uzywajac Javy i Axisa. Jednakrównie dobrze mógłby to byc serwer stworzony w PHP czy tez w Pythonie. Opisany nizej sposób tworzeniaklienta byłby taki sam. Taka niezaleznosc mozliwa jest dzieki wykorzystania plików WSDL (Web ServicesDescription Langue, kompletny opis standardu: http://www.w3.org/TR/wsdl).

Udostepnionemu w sieci serwisowi, zawsze towarzyszy plik WSDL. Dawniej pliki te musiały byc wcałosci pisane recznie, teraz wiekszosc narzedzi generuje je automatycznie. Tak jest równiez w ApacheAxis. Nasz przykładowy serwis dostepny jest pod adresem http://localhost:8080/axis/services/InterfejsSerwisu ,a odpowiadajacy mu plik WSDL pod adresem http://localhost:8080/axis/services/InterfejsSerwisu?wsdl .

Dzieki temu własnie plikowi, mozliwe jest stworzenie aplikacji klienta, nie znajac w ogóle szczegółówimplementacyjnych serwera. Wykorzystuje sie tylko wymienione w WSDL metody i ich argumenty.

Istnieja dwie główne metody tworzenia klienta przy uzyciu Axis:

• klient statyczny, korzystajacy z plików .java wygenerowanych z pliku WSDL

• klient dynamiczny, na biezaco analizujacy deskryptor WSDL

2.6.1 Klient statycznyPrzy tworzeniu klienta statycznego, skorzystamy znowu z klasy WSDL2Java (patrz punkt 2.5.2.1).

2.6.1.1 Generacja plików Java z WSDL

Wynikiem działania klasy Java2WSDL bedzie plik WSDL, który zawiera informacje na temat naszego(docelowego) serwisu. Z pomoca tego pliku, jestesmy w stanie wygenerowac klasy, które posłuza nam doprawidłowego udostepnienia serwisu. Robimy to za pomoca polecenia

java org.apache.axis.wsdl.WSDL2Java-o . \-Nhttp://localhost:8080/axis/services/InterfejsSerwisu \serwis.klient \http://localhost:8080/axis/services/InterfejsSerwisu?wsdl

• -o . - pliki docelowe maja znalezc sie w biezacym katalogu

• -Nhttp:... serwis.klient - mapowanie adresu na przestrzen nazw nowego pakietu

• http://... - lokalizacja pliku wsdl (moze to byc równiez plik)

Dokładniejsze wyjasnienie uzycia klasy WSDL2Java znajduje sie pod adresem http://ws.apache.org/axis/java/reference.html#WSDL2JavaReference .Wynikiem działania powinny byc pliki:

• Serwis/ InterfejsSerwisuSoapBindingStub.java - kod klienta

• Serwis/InterfejsSerwisuServiceLocator.java - klasa pomaga łaczyc sie z serwisem na przygotowanymporcie

• serwis/silnik/Adres.java - implementacja złozonego typu

• Serwis/InterfejsSerwisu.java - interfejs klasy InterfejsSerwisuSoapBindingStub

• Serwis/InterfejsSerwisuService.java - interfejs klasy InterfejsSerwisuServiceLocator

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 37

2.6.1.2 Tworzenie kodu klienta

Nalezy teraz stworzyc od podstaw kod klienta, który połaczy sie z serwerem za pomoca klasySerwis/InterfejsSerwisuServiceLocator.java. Umiescimy go w osobnym pakiecie serwis.klient, klase nazwiemyKlient (listing 2.6.1.5). Trzeba zaimportowac wszystkie klasy z pakietu Serwis a takze klase Adres. Klientposiada tylko funkcje main(). Własciwie tylko dwie linie wymagaja komentarza:

InterfejsSerwisuService locator =new InterfejsSerwisuServiceLocator();

InterfejsSerwisu service =locator.getInterfejsSerwisu();

Te dwie linie najpierw tworza obiekt, a potem za jego pomoca ustawiaja odpowiednie połaczenia (klasa In-terfejsSerwisuSoapBindingStub) i tworza interfejs, który umozliwia bezposrednie połaczenie z serwerem.

Pozostałe linie to juz wywołanie odpowiednich funkcji na serwerze: hello() i getIP() z parametrempodanym w linii polecen.

2.6.1.3 Kompilacja kodu

Kod nalezy z kompilowac z nadkatalogu :

javac Serwis/*.java serwis/silnik/Adres.java serwis/klient/Klient.java

2.6.1.4 Uruchomienie klienta

W linii polecen mozna podac adres hosta którego IP chcemy poznac. Domyslnym hostem jest vercom.pl

java serwis/klient/Klient inotel.pl

Odpowiedz:

Metoda Hello odpowiada nam: Hello World!Adres hosta inotel.pl to 193.109.91.135

2.6.1.5 Kod klienta

package serwis.klient;import Serwis.*;import serwis.silnik.Adres;import java.rmi.RemoteException;import javax.xml.rpc.ServiceException;public class Klient {

public static void main(String[] args)throws ServiceException, RemoteException {

String host=null;InterfejsSerwisuService locator =

new InterfejsSerwisuServiceLocator();InterfejsSerwisu service =

locator.getInterfejsSerwisu();System.out.println("Metoda Hello odpowiada nam: " +

service.hello());if (args.length == 1)

host = args[0];else

host = "vercom.pl";Adres adr = new Adres();

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 38

adr = service.getIP(host);System.out.println("Adres hosta "+

adr.getNazwa() +" to "+adr.getAdres());

}}

2.6.2 Klient dynamicznyKlient dynamiczny, w odróznieniu od statycznego, nie wymaga generowania nowego szkieletu z plikuWSDL za kazdym razem, gdy zmianie ulegna parametry serwisu na serwerze. Tutaj połaczenie tworzonejest bezposrednio w jedynym pliku z kodem wykonywalnym.

2.6.2.1 Tworzenie kodu zródłowego

Klient dynamiczny łaczy sie za pomoca tzw. “koncówki” (ang.: endpoint). Jest to adres usługi któraudostepniamy, czyli w tym przypadku http://localhost:8080/axis/services/InterfejsSerwisu .Zapisujemy ten adres do zmiennej.

String endpoint ="http://localhost:8080/axis/services/InterfejsSerwisu";

Nastepnie tworzymy nowy obiekt klasy Service (klasa uzywana jako poczatkowa klasa do uzyskaniadostepu do Web Services. Zazwyczaj uzywana z podanym plikiem WSDL i obiektem klasy Call.ServiceAPI http://ws.apache.org/axis/java/apiDocs/org/apache/axis/client/Service.html),a z niego obiekt Call (klasa uzywana do prawdziwego uruchomienia połaczenia z Web Service’m. Mozebyc poczatkowo wypełniona za pomoca dokumentu WSDL (w konstruktorze klasy Service) lub tez moznawypełnic dane recznie,Call API http://ws.apache.org/axis/java/apiDocs/org/apache/axis/client/Call.html).Wszelkie potrzebne typy atrybutów beda równiez przekazane tym obiektom.

Service service = new Service();Call call = (Call) service.createCall();

Kolejnym krokiem jest reczne wypełnienie niezbednych wartosci. Najpierw adres koncówki serwisu (set-TargetEndpointAddress() ), nastepnie nazwa metody do wywołania. Klasa Qname (QName API http://ws.apache.org/axis/java/apiDocs/javax/xml/namespace/QName.html)słuzy do zamiany nazwy na zgodna ze standardem XML Schema Part2: Datatypes specification.

call.setOperationName(new QName("", "hello") );

Nastepnie za pomoca polecenia invoke() zgłaszamy zadanie serwerowi. Jako parametr invoke() przyjmujetablice obiektów (wazne, by kazdy z nich był zgodny z prawdziwymi parametrami metody). W przypadkumetody hello() nie sa potrzebne zadne parametry, dlatego przesyłana jest pusta tablica (0 elementów).Zwracany jest obiekt (bez okreslonego typu). W tym przypadku wiemy, ze jest to łancuch znaków, dlategouzywamy metody toString().

String odpHello = call.invoke(new Object[0]).toString();

Niestety nie zawsze mozna sobie tak łatwo poradzic. Bardziej skomplikowana metoda jest getIP(). Przyj-muje ona parametr, a co gorsza, zwraca niestandardowy typ.

Skorzystamy z obiektów zainicjalizowanych juz wczesniej. Zmienimy nazwe metody na getIP,

call.setOperationName(new QName("", "getIP") );

a nastepnie dodamy argument (parametr)

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 39

call.addParameter("host",org.apache.axis.Constants.XSD_STRING,javax.xml.rpc.ParameterMode.IN);

Metoda addParameter() przyjmuje po kolei:

• nazwe parametru (musi byc zgodna z WSDL)

• typ parametru

• rodzaj parametru (wyjsciowy OUT, wejsciowy IN, mieszany INOUT)

Trzeba teraz zajac sie zwracana wartoscia. Niestety jest to obiekt stworzony przez nas, tak wiec nie moznaskorzystac ze standardowych meto dostepnych w klasie Call. Musimy zdefiniowac nasz nowy typ, a nastep-nie stworzyc klase, która zostanie uzyta do umieszczenia wartosci z oryginalnego obiektu.

Po pierwsze, tworzymy nowy obiekt typu QName, umozliwiajacy mapowanie złozonego typu w po-danej przestrzeni nazw.

QName qname = new QName("urn:Serwis", "Adres");

Trudniejszym fragmentem jest

call.registerTypeMapping(Adres.class,qname,new org.apache.axis.encoding.ser.

BeanSerializerFactory(Adres.class, qname),new org.apache.axis.encoding.ser.

BeanDeserializerFactory(Adres.class, qname));

Ten fragment kodu odpowiada za mapowanie z obiektu typu Adres zdefiniowanego na serwerze (listingponizej, odpowiedni opis w pliku WSDL: punkt ??) do naszego obiektu. Z pliku WSDL mozemy odczytac,ze typ złozony (ang. complex type) składa sie z dwóch pól typu String:

<complexType name="Adres"><sequence>

<element name="nazwa" nillable="true" type="soapenc:string"/><element name="adres" nillable="true" type="soapenc:string"/>

</sequence></complexType>

Odczytalismy równiez ich nazwy: nazwa i adres. Musimy teraz stworzyc klase, która bedzie udawacoryginalna klase Adres której kodu nie znamy. Musi ona zawierac pola takie jak podano w pliku WSDL, atakze musi koniecznie posiadac odpowiednio nazwane metody umozliwiajace dostep do tych pól. Nazwymetod sa w formacie:

• setNazwaPola() (setNazwa(), setAdres())

• getNazwaPola() (getNazwa(), getAdres())

Kod klasy Adres prezentuje sie nastepujaco:

package klient;public class Adres {

private String adres;private String nazwa;

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 40

public void setAdres( String adres ) {this.adres = adres;

}public String getAdres() {

return adres;}public void setNazwa( String nazwa ) {

this.nazwa = nazwa;}public String getNazwa() {

return nazwa;}

}

Tak na marginesie, uzycie metod set i get jest ogólnie przyjetym standardem dostepu do zmiennych pub-licznych w klasach. Sama zmienne po utworzeniu tych funkcji powinny byc zmienione na prywatne.

Wracajac do metody registerTypeMapping() pobiera ona argumenty:

• wskaznik na klase docelowa (klase, nie jej instancje)

• obiekt mapujacy nazwe

• nowy obiekt odpowiadajacy za zakodowanie danych do odpowiedniego formatu na serwerze

• nowy obiekt odpowiadajacy za zdekodowanie danych do odpowiedniego formatu w aplikacji klienta

Po wykonaniu tego polecenia, obiekt call wie juz wszystko o naszym typie: co to jest klasa Adres i jak sienia posługiwac. Teraz wystarczy mu powiedziec, ze ma sie ta wiedza posłuzyc (mapowac na nasza klaseAdres) interpretujac wartosc zwracana przez metode invoke():

call.setReturnType(qname,Adres.class);

Teraz dodajemy adres do sprawdzenia. Powiazalismy juz ta zmienna z jej nazwa (host) i typem w metodzieaddParameter().

Object[] inParams = new Object[1];inParams[0] = new String("vercom.pl");

Gdyby parametrów było wiecej, dodawalibysmy je w kolejnych polach tablicy (oczywiscie nalezałobystworzyc wieksza tablice). Ostatnim krokiem jest utworzenie instancji klasy Adres, a nastepnie odpalenienaszego serwisu:

Adres a = new Adres();a = ((Adres)call.invoke(inParams));

Teraz, korzystajac z odpowiednich getterów, mozna odczytac zwrócone wartosci.

System.out.println("Odczytana nazwa to "+a.getNazwa()+" a adres "+a.getAdres());

Odpowiedzia powinno byc

Klient dynamiczny uslyszal Hello World!Odczytana nazwa to vercom.pl a adres 193.109.91.136

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 41

2.6.2.2 Kod klienta

package klient;import javax.xml.namespace.QName;import org.apache.axis.client.Call;import org.apache.axis.client.Service;import klient.Adres;public class Klient {

public static void main(String args[]){try {

String endpoint ="http://localhost:8080/axis/services/InterfejsSerwisu";

Service service = new Service();Call call = (Call) service.createCall();

call.setTargetEndpointAddress( new java.net.URL(endpoint) );call.setOperationName(new QName("", "hello") );String odpHello = call.invoke(new Object[0]).toString();System.out.println("Klient dynamiczny uslyszal "+odpHello);

call.setOperationName(new QName("", "getIP") );

call.addParameter("host",org.apache.axis.Constants.XSD_STRING,javax.xml.rpc.ParameterMode.IN);

QName qname = new QName("urn:Serwis", "Adres");call.registerTypeMapping(Adres.class,qname,new org.apache.axis.encoding.ser.

BeanSerializerFactory(Adres.class, qname),new org.apache.axis.encoding.ser.

BeanDeserializerFactory(Adres.class, qname));

call.setReturnType(qname,Adres.class);

Object[] inParams = new Object[1];inParams[0] = new String("vercom.pl");

Adres a = new Adres();a = ((Adres)call.invoke(inParams));System.out.println("Odczytana nazwa to "+

a.getNazwa()+" a adres "+a.getAdres());

} catch (Exception e) {System.err.println(e.toString());

}}

}

ROZDZIAŁ 2. WEB SERVICES Z WYKORZYSTANIEM APACHE AXIS 42

2.7 Pliki do pobraniaWszystkie uzyte w tym artykule kody zródłowe znalezc mozna pod adresem pliki/axis-zrodla.zip.

Rozdział 3

Tworzenie i korzystanie z Web Servicesw PHP

3.1 WstepPHP, jako skryptowy jezyk wykorzystywany głównie na stronach internetowych, nie mógł pozostac obojet-nym wobec powstajacej technologii Web Services. Powstało kilka wersji implementacji protokołu SOAP,a w chwili obecnej istnieja trzy główne:

• wkompilowana w PHP w wersji 5.0 i wyzszych - http://pl.php.net/manual/en/ref.soap.php

• czesc pakietu PEAR http://pear.php.net/

• biblioteka nusoap http://sourceforge.net/projects/nusoap/

Pierwsza implementacja napisana jest w jezyku C - jest szybsza od pozostałych. Nie jest to jednak bardzoznaczaca róznica, chyba ze tworzymy WS, który bedzie obciazony bardzo duza iloscia połaczen. Z koleipozostałe dwie implementacje (PEAR i nusoap) posiadaja duzo wiecej funkcji. Tutaj zostana opisanepierwsze dwie implementacje.

3.2 Wbudowany SOAPRozszerzenie pojawiło sie w PHP w wersji 5.0. Moze byc uzyte do pisania zarówno serwera, jak i klienta.Obsługuje standardy SOAP 1.1, SOAP 1.2 i WSDL 1.1 .

3.2.1 InstalacjaDo prawidłowego działania potrzebne sa dwa komponenty:

• Serwer http, np Apache

• PHP w wersji co najmniej 5.0 wraz z modułem SOAP

Opisze tutaj, jak krok po kroku skompilowac i zainstalowac PHP w wersji 5.x. na Apache 2.x. Ten opis in-stalacji jest oparty o opis ze strony http://www.pl.php.net/manual/pl/install.unix.apache2.php .

Potrzebujemy konieczna do kompilacji SOAP biblioteke libxml2 (GNOME xml library). Jej najnowszawersja znajduje sie pod adresem ftp://xmlsoft.org/LATEST_LIBXML2 . Pobierzmy ja stamtad i roz-pakujmy (tar -zxf LATEST_LIBXML2). Nastepnie nalezy przejsc do utworzonego katalogu i wydacpolecenie

./configure --prefix=/usr/local/lib/libxml2

43

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 44

Jezeli przeszło bez problemów, nalezy teraz skompilowac program

make

I jezeli instalujemy do katalogu systemowego, przelogowac sie na konto root

su

oraz wydac komende instalacji

make install

Teraz mozemy juz instalowac apache i PHP.Najpierw nalezy sciagnac zródła ze stron http://httpd.apache.org/download.cgi i http://www.php.net/downloads.php

i rozpakowac je

tar -zxf httpd-2_0_NN.tar.gztar -zxf php-NN.tar.gzcd httpd-2_0_NN./configure --enable-somakesumake install

W tym momencie Apache jest dostepny w katalogu /usr/local/apache2, skonfigurowany ze wsparciemmodułów. Zeby przetestowac instalacje uzyj swojego polecenia startujacego serwer, np.

/usr/local/apache2/bin/apachectl start

i zatrzymaj go nastepnie aby przejsc do instalacji PHP

/usr/local/apache2/bin/apachectl stop.cd ../php-NN

Teraz skonfiguruj PHP. W tym miejscu mozesz powiedziec, co ma zawierac instalacja PHP. Polecenie ./con-figure –help wyswietli mozliwe opcje. Tutaj wykonamy prosta instalacje ze wsparciem SOAP i MySQL.Sciezka do apxs (lub apxs2) moze byc inna na Twoim systemie.

./configure --with-apxs2=/usr/local/apache2/bin/apxs \--enable-soap \--with-libxml-dir=/usr/local/lib/libxml2 \

makemake install

Jesli zechcesz zmienic opcje juz po instalacji, musisz tylko powtórzyc ostatnie 3 kroki. Rekompilacjaapache nie jest potrzebna. Konieczne jest jednak jego restart. Zauwaz, ze jesli nie jest inaczej zaznaczone,make install zainstaluje równiez PEAR i inne narzedzie PHP.

Ustawmy teraz php.ini

cp php.ini-dist /usr/local/lib/php.ini

Zedytuj plik httpd.conf aby ładował moduł PHP. Sciezka po prawej stronie wpisu LoadModule musiwskazywac sciezke do modułu PHP na Twoim systemie. Polecenie make install powinno dodac ten wpisza Ciebie, ale jednak lepiej sie upewnic.

LoadModule php5_module libexec/libphp5.so

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 45

Musisz równiez ustawic, aby Apache rozpoznawało pliki o danym rozszerzeniu (w tym przykładzie .php i.phtml) jako PHP. Nalezy dodac wpis

AddType application/x-httpd-php .php .phtml

Nastepnie uruchomimy ponownie serwer Apache:

/usr/local/apache2/bin/apachectl start

Najpierw nalezy pobrac zródła programu ze strony. Rozpakowujemy je poleceniem

tar -jxf php-5.x.tar.bz2

lub za pomoca graficznego narzedzia. Nastepnie przechodzimy do katalogu z rozpakowanymi zródłami.Za wyswietlenie wszystkich opcji odpowiada polecenie

./configure --help

My uzyjemy tylko

./configure --enable-soap --with-apx

Czyli ze chcemy uzywac SOAP z serwerem Apache 1.x (inne konfiguracje http://www.php.net/manual/pl/install.php)Nastepnie mozna juz wrócic do poprzedniego uzytkownika, przejsc do katalogu ze zródłami php i

ponownie spróbowac

./configure --enable-soap

Nastepnie

makesumake install

Wynikiem powinno byc

Installing PHP SAPI module: cgiInstalling PHP CGI into: /usr/local/bin/Installing PEAR environment: /usr/local/lib/php/[PEAR] Archive_Tar - installed: 1.1[PEAR] Console_Getopt - installed: 1.2[PEAR] PEAR - installed: 1.3.6Wrote PEAR system config file at: /usr/local/etc/pear.confYou may want to add: /usr/local/lib/php to your php.ini include_path[PEAR] HTML_Template_IT- installed: 1.1[PEAR] Net_UserAgent_Detect- installed: 2.0.1[PEAR] XML_RPC - installed: 1.4.0Installing build environment: /usr/local/lib/php/build/Installing header files: /usr/local/include/php/Installing helper programs: /usr/local/bin/program: phpizeprogram: php-config

Installing man pages: /usr/local/man/man1/page: phpize.1page: php-config.1

W tym momencie powinnismy juz miec zainstalowane PHP razem z rozszerzeniem - SOAP.

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 46

3.2.2 KonfiguracjaNazwa Domyslnie Wyjasnienie

soap.wsdl_cache_enabled 1 zapamietac pliki WSDL w pamieci podrecznejsoap.wsdl_cache_dir /tmp gdzie przechowywac pliki WSDLsoap.wsdl_cache_ttl 86400 po jakim czasie kasowac zapamietane pliki WSDLWszystkie te opcje mozna ustawic w pliku php.ini, lub tez uzywajac komendy ini_set().W tym momencie skonczylismy konfiguracje i instalacje rozszerzenia do PHP obsługujacego protokół

SOAP. Przejdzmy teraz do punktu 3.2.3, gdzie nauczymy sie tworzyc serwer WS w PHP.

3.2.3 Tworzenie serweraKod serwera zawiera sie w kilku krótkich liniach, jednak w przeciwienstwie do serwera w PEAR, nalezyniestety recznie stworzyc plik WSDL. Z pewnoscia w dalszych wersjach rozszerzenia do PHP pojawi sierówniez automatyzacja tej czynnosci, jednak teraz trzeba wykazac sie znajomoscia WSDL.

Stwórzmy sobie klase Sieciowa, która bedzie posiadała metode getIP(), zwracajaca adres IP hostapodanego w parametrze. Zeby nieco skomplikowac sprawe, bedzie zwracała równiez nazwe tego hosta.Całosc zgrupujemy w obiekt klasy Adres, składajacej sie z dwóch stringów.

Najpierw stworzymy funkcje getIP(), która zaimportuje i wykona metode o identycznie brzmiacejnazwie z klasy Sieciowa.

function getIP($host) {include("Sieciowa.php");$importowana = new Sieciowa;return $importowana->getIP($host);

}

Instancja serwera powstanie na bazie stworzonego wczesniej pliku WSDL

$server = new SoapServer("Interfejs.wsdl");

Nastepnie wystepuje fragment odpowiedzialny za udostepnienie metod na zewnatrz i uruchomienie nasłuchuserwera

$server->addFunction("getIP");$server->handle();

Oto kody wszystkich klas:

• kod Serwera

<?phpfunction getIP($host) {

include("Sieciowa.php");$importowana = new Sieciowa;return $importowana->getIP($host);

}$server = new SoapServer("Interfejs.wsdl");$server->addFunction("getIP");$server->handle();?>

• klasa Sieciowa

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 47

<?phpclass Sieciowa{

function getIP($host){include("Adres.php");$adr = new Adres();$adr->nazwa = $host;$adr->adres = gethostbyname($host);return $adr;

}}?>

• klasa Adres

<?phpclass Adres{

public $nazwa;public $adres;

}?>

3.2.4 Tworzenie klientaPisanie klienta ogranicza sie własciwie do podania adresu pliku WSDL

$client = new SoapClient( "http://app.vercom.pl/~rob/Interfejs.wsdl" );

wykonania funkcji na utworzonym obiekcie.

$wynik = $client->getIP("inotel.pl");

i odczytu rezultatu

print "Serwer $wynik->nazwa ma adres $wynik->adres";

Kod klienta:

<?php$client = new

SoapClient("http://app.vercom.pl/~rob/Interfejs.wsdl"

);$wynik = $client->getIP("inotel.pl");print "Serwer $wynik->nazwa ma adres $wynik->adres";

?>

3.3 PEAR SOAPInna implementacja protokołu SOAP jest PEAR SOAP, http://pear.php.net/package/SOAP . Wydajesie byc ona na obecna chwile bardziej rozbudowana od odpowiednika PHP-SOAP. Serwer posiada naprzykład bardzo pomocna funkcje automatycznego tworzenia pliku WSDL.

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 48

3.3.1 InstalacjaDo prawidłowego działania potrzebne sa dwa komponenty:

• Serwer http, np Apache

• PHP w wersji co najmniej 5.0

Opis instalacji znajduje sie w punkcie 3.2.1. PEAR, jesli nie zaznaczymy inaczej, jest instalowany standar-dowo z PHP. Zainstalowany w systemie, udostepnia narzedzie słuzace instalacji dodatkowych pakietów.Dlatego ich instalacja ogranicza sie do komend:

pear install Mail_Mimepear install Net_URLpear install Net_Socketpear install HTTP_Requestpear install --force Net_DIMEpear install --force SOAP

Przełacznik –force oznacza ze akceptujemy wersje rózna od stable.

3.3.2 Tworzenie serweraStwórzmy sobie klase Sieciowa, która bedzie posiadała metode getIP(), zwracajaca adres IP hosta po-danego w parametrze. Zeby nieco skomplikowac sprawe, bedzie zwracała równiez nazwe tego hosta.Całosc zgrupujemy w obiekt klasy Adres, składajacej sie z dwóch stringów.

W pierwszym kroku, załaczamy odpowiednie biblioteki

require_once (’SOAP/Server.php’); //tworzenie web servicerequire_once (’SOAP/Disco.php’); //tworzenie automatyczne WSDL

Nastepnie utworzymy pole $__dispatch_map

var $__dispatch_map = array ();

Jest to tablica, która bedzie zawierac mapowanie typów, zarówno złozonych jak i prostych. Jest onakonieczna, gdyz w PHP nie ma wprost zdefiniowanych typów zmiennych, a jest to konieczne do komu-nikacji za pomoca SOAP. Ta tablice wypełnimy w konstruktorze. Schemat wypełniania __dispath_mapwyglada nastepujaco:

$this->__dispatch_map[’NAZWA_FUNKCJI_DO_EKSPORTU’] =array (’in’ =>array (

’ARG1’ =>’TYP_ARG1’,’ARG2’ =>’TYP_ARG2’),

’out’ =>array (’NAZWA_WYJSCIA’ =>’TYP_WYJSCIA’),

);

Na przykład

$this->__dispatch_map[’dodaj’] =array (’in’ =>array (

’liczba1’ =>’integer’,

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 49

’liczba2’ =>’integer’),

’out’ =>array (’suma’ =>’integer’),

);$this->__dispatch_map[’podziel’] =

array (’in’ =>array (

’liczba1’ =>’integer’,’liczba2’ =>’integer’),

’out’ =>array (’iloraz’ =>’float’),

);

W pliku WSDL pojawi sie

...<message name="dodajRequest">

<part name="liczba1" type="xsd:integer"/><part name="liczba2" type="xsd:integer"/>

</message>...

Jezeli trafimy na jakis złozony typ, nalezy go tez odpowiednio zapisac:

$this->__dispatch_map[’getIP’] =array (’in’ =>array (’host’ =>’string’),’out’ =>array (’adres’ => ’{urn:Interfejs}Adres’),);

$this->__typedef[’adres’] =array(

’nazwa’ => ’string’,’adres’ => ’string’,

);

Gdzie {urn:Interfejs} to przestrzen nazw projektu. W pliku WSDL, oprócz zwyczajowego

<message name="getIPResponse"><part name="adres" type="tns:Adres"/>

</message>

musi pokazac sie objasnienie typu adres:

<types><schema targetNamespace="urn:Interfejs">

<complexType name="adres"><all>

<element name="nazwa" type="xsd:string"/><element name="adres" type="xsd:string"/>

</all></complexType>

</schema></types>

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 50

Majac okreslone typy, mozna stworzyc funkcje (najwygodniej o takiej samej nazwie jak docelowa) któraodwoła sie do oryginalnej funkcji (znajdujacej sie w klasie niedostepnej z poziomu klienta). Najprostszykod wyglada nastepujaco:

function getIP($host){include "Sieciowa.php";$importowana = new Sieciowa;return $importowana->getIP($host);

}

Dla kazdej eksportowanej funkcji tworzymy wpis w __dispath_map i importujemy odpowiednia metode.Po ustawieniu wszystkich tych opcji, mozna juz odpalic serwer. Na poczatek trzeba ustawic zmienna

odpowiedzialna za przestrzen nazw

$namespace="Interfejs";

Kolejnym krokiem jest odpalenie serwera PEAR - SOAP

$server = new SOAP_Server ();

Stworzenie instancji klasy która bedzie widoczna na zewnatrz

$webservice = new Interfejs();

Dodanie klasy do serwera, drugi argument to przestrzen nazw

$server->addObjectMap ($webservice,’http://schemas.xmlsoap.org/soap/envelope/’);

Radzenie sobie z zadaniami POST

if (isset ($_SERVER[’REQUEST_METHOD’]) &&$_SERVER[’REQUEST_METHOD’] == ’POST’)

{$server->service ($HTTP_RAW_POST_DATA);

}else{

$disco = new SOAP_DISCO_Server ($server, $namespace);if (isset ($_SERVER[’QUERY_STRING’]) &&

Serwer DISCO, jezeli parametrem jest "wsdl", generuje dokument WSDL

strcasecmp ($_SERVER[’QUERY_STRING’], ’wsdl’) == 0){header ("Content-type: text/xml");echo $disco->getWSDL ();

}else

{echo $disco->getDISCO ();

}}

Całosc kodu przedstawia sie nastepujaco:

• klasa Interfejs

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 51

<?phprequire_once (’SOAP/Server.php’); //tworzenie web servicerequire_once (’SOAP/Disco.php’); //tworzenie automatyczne WSDL/** Klasa z ktorej bierzemy funkcje (jest w pliku klasa.php)* nie musi byc zmieniana (przerabiana pod wspolprace z WS)*/class Interfejs{//tutaj beda przechowywane nazwy eksportowanych funkcjivar $__dispatch_map = array (); wraz z argumentami i ich typami

/** Konstruktor, dzieki ktoremu mamy pewnosc,* ze tablica __dispatch_map zostanie wypelniona wg schematu:** $this->__dispatch_map[’NAZWA_FUNKCJI_DO_EKSPORTU’] =* array (* ’in’ =>array (* ’ARG1’ =>’TYP_ARG1’,* ’ARG2’ =>’TYP_ARG2’* ),* ’out’ =>array (* ’NAZWA_WYJSCIA’ =>’TYP_WYJSCIA’* ),* );*/function Interfejs (){

$this->__dispatch_map[’getIP’] =array (

’in’ =>array (’host’ =>’string’),’out’ =>array (’adres’ => ’{urn:Interfejs}Adres’),

);$this->__typedef[’adres’] =

array(’nazwa’ => ’string’,’adres’ => ’string’,

);}/*kazda funkcje trzeba importowac i zadbac zeby dzialala*/

function getIP($host){include "Sieciowa.php";$importowana = new Sieciowa;return $importowana->getIP($host);

}}$namespace="Interfejs";//odpalenie servera PEAR - SOAP$server = new SOAP_Server ();//odpalenie klasy$webservice = new Interfejs();ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache//dodanie klasy do serwera, drugi arg to przestrzen nazw$server->addObjectMap ($webservice,

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 52

’http://schemas.xmlsoap.org/soap/envelope/’);//radzenie sobie z zadaniami POSTif (isset ($_SERVER[’REQUEST_METHOD’]) &&

$_SERVER[’REQUEST_METHOD’] == ’POST’){

$server->service ($HTTP_RAW_POST_DATA);}

else{

// serwer DISCO, jezeli parametrem jest "wsdl", generuje WSDL$disco = new SOAP_DISCO_Server ($server, $namespace);if (isset ($_SERVER[’QUERY_STRING’]) &&

strcasecmp ($_SERVER[’QUERY_STRING’], ’wsdl’) == 0){

header ("Content-type: text/xml");echo $disco->getWSDL ();

}else

{echo $disco->getDISCO ();

}}

?>

• klasa Sieciowa

<?phpclass Sieciowa{

function getIP($host){include("Adres.php");$adr = new Adres();$adr->nazwa = $host;$adr->adres = gethostbyname($host);return $adr;

}}?>

• klasa Adres

<?phpclass Adres{

public $nazwa;public $adres;

}?>

3.3.3 KlientAplikacja klient jest zdecydowanie prostsza niz serwer.

<?phprequire_once ’SOAP/Client.php’;$wsdl_url =’http://192.168.1.213/Interfejs.php?wsdl’;

ROZDZIAŁ 3. TWORZENIE I KORZYSTANIE Z WEB SERVICES W PHP 53

$WSDL = new SOAP_WSDL($wsdl_url);$client = $WSDL->getProxy();$wynik = $client->getIP("wp.pl");print "Serwer $wynik->nazwa ma adres $wynik->adres";?>

Podajemy adres pliku WSDL

$wsdl_url = ’http://192.168.1.213/Interfejs.php?wsdl’;

Tworzymy z niego nowy obiekt

$WSDL = new SOAP_WSDL($wsdl_url);

Tworzymy proxy, ktore podłaczy sie do serwera

$client = $WSDL->getProxy();

Teraz za pomoca zmiennej $client, mozemy wywoływac wszystkie funkcje serwera

$wynik = $client->getIP("wp.pl");print "Serwer $wynik->nazwa ma adres $wynik->adres";

I to własciwie wszystkie kroki potrzebne do stworzenia klienta. Zwrócmy uwage na łatwosc z jaka odczy-tujemy złozony typ Adres.

3.4 Pliki do pobraniaWszystkie uzyte w tym artykule kody zródłowe znalezc mozna pod adresem pliki/php-zrodla.zip .

Rozdział 4

Web Services z uzyciem Eclipse WebTools Platform

4.1 WstepProjekt Eclipse Web Tools Platform (WTP) jest rozszerzeniem platformy Eclipse odpowiedzialnym zatworzenie aplikacji J2EE. Zawiera zestaw narzedzi pomocnych przy tworzeniu, kompilacji i udostepnianiuWeb Services. Sa to edytory plików WSDL i XML (w tym takze edytory graficzne), kreatory tworzeniaserwera (4.4.2) i klienta (4.4.4), a takze eksplorator WS (4.4.7).

Ten dokument zawiera opis instalacji, konfiguracji oraz szczegółowe przykłady tworzenia i testowaniaWeb Services przy pomocy srodowiska Eclipse i pluginu Eclipse Web Service Tools.

4.2 Uzyte komponenty• Java

Wymagane jest srodowisko Java. Tutaj uzyto SUN Java 2 Platform Standard Edition DevelopmentKit 5.0 update 4, dostepne pod adresem http://java.sun.com/j2se/1.5.0/download.jsp .

• EclipsePosiadanie Eclipse jest równiez niezbedne. Tutaj uzyto wersji eclipse-SDK-3.1-linux-gtk.tar.gz, innewersje znajduja sie pod adresem http://eclipse.org/downloads/index.php

• Serwer (web container)Aplikacja która zbudujemy, bedzie docelowo dostepna dla całego swiata. Aby to umozliwic, sko-rzystamy z zewnetrznego serwera. Wybralismy darmowy serwer dostepny w ramach organizacjiApache: Jakarta Tomcat (Jakarta Tomcat http://jakarta.apache.org/tomcat/). Mozliwe jestrówniez uzycie innego serwera. W tym tutorialu uzyto Tomcata 5.5 nasłuchujacego na porcie 8080(standardowy port Tomcata).

• Platforma Web ToolsAby dodac nowe funkcje obsługujace Web Services nalezy zainstalowac Web Tools Platform zestrony http://download.eclipse.org/webtools/downloads . Tutaj uzyto wersji wtp-all-in-one-0.7-linux-gtk.tar.gz . Instalacja pluginu polega na rozpakowaniu go i przegraniu do katalogu z eclipse,do podkatalogu plugins.

4.3 Instalacja Web Tools PlatformEclipse posiada bardzo ciekawe narzedzie do instalacji oraz aktualizowania dodatków. Opisze tutaj jak zajego pomoca zainstaloac WTP.

54

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 55

• Z menu Help wybieramy Software Updates ->Find and Install. W nowym okienku zaznaczamySearch for new features to install, a nastepnie klikamy Next

• zaznaczamy Eclipse.org update site i klikamy Finish

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 56

• wybieramy najblizszy nam serwer i klikamy ok

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 57

• teraz nalezy rozszerzyc liste Eclipse.org update site i wybrac WTP, a nastepnie kliknac Next

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 58

• akceptujemy licencje i klikamy next

• klikamy finish aby rozpoczac instalacje

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 59

• jesli pojawi sie okienko, klikamy Install all

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 60

• nastapi instalacja pluginów

• po zakonczeniu instalacji zostaniemy zapytani czy chcemy ponownie uruchomic eclipse. Zgadzamysie.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 61

• Jesli w trakcie instalacji pojawi sie pytanie o instalacje dodatkowych pluginów wymaganych do dzi-ałania, nalezy kliknac przycisk Select Required, co spowoduje zainstalowanie minimalnego zestawupotrzebnego do pracy.

• Mozna równiez własnorecznie zainstalowac plugin, poprzez sciagniecie, rozpakowanie go i prze-granie do katalogu z Eclipse, do podkatalogu plugins.

• Na koniec nalezy równiez sie upewnic, ze zmienne systemowe sa dobrze ustawione: Window->Preferences->Java->Installed JREs powinno wskazywac na instalacje Javy.

Jezeli plugin został poprawnie zainstalowany, pojawi sie nowa mozliwosc wyswietlania (perspective):J2EE. Aby przełaczyc sie do niej, nalezy:

kliknac ikone listy perspektyw

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 62

wybrac “Other”

wybrac J2EE i kliknac OKPo lewej stronie powinien pokazac sie zmodyfikowany panel “Project Explorer”

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 63

Ostatnim krokiem jest ustawienie mozliwosci tworzenia wielu modułów w pojedynczym projekcie. Taopcja znajduje sie w menu Window -> Preferences... -> J2EE Project.

4.4 Programowanie Web Services z uzyciem WTPProgramowanie aplikacji z uzyciem WTP jest o wiele łatwiejsze i szybsze niz pisanie przy uzyciu samegoApache Axis (2.1). Mozliwe jest stworzenie Web Service, nie zagłebiajac sie zbyt głeboko w strukturedziałania WS.

Niestety, funkcjonalnosc WTP jest w tej chwili ograniczona. Istniejaca obecnie wersja 0.7 jest wersjarozwojowa, której brakuje miedzy innymi mozliwosci łatwego udostepnienia aplikacji na zewnetrznym

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 64

serwerze (mozliwe jest jednak udostepnienie za pomoca pliku WAR). Ta opcje bedzie uwzgledniona wdalszych wersjach.

4.4.1 Tworzenie nowego projektuAby stworzyc nowy projekt, z menu nalezy wybrac File -> New -> Project. W nowym oknie nalezywybrac Web->Dynamic Web Project.

Po kliknieciu Next, otworzy sie kreator tworzenia projektu.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 65

Nalezy kliknac New. Otworzy sie kolejne okienko, gdzie nalezy wpisac nazwe projektu. Do uru-chomienia, aplikacja sieciowa potrzebuje serwera, który musimy zdefiniowac. Nalezy kliknac opcje New,aby stworzyc nowy serwer.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 66

W nowo otwartym oknie, wybieramy nasz docelowy serwer (w tym przypadku Tomcat 5.5) .

Po kliknieciu Next, pojawi sie okno dodawania serwera. W nowym oknie wpisujemy lub znajdujemykatalog instalacyjny Tomcata oraz mamy mozliwosc zmiany ustawionego domyslnie (4.3) srodowiska Javy.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 67

Klikamy Finish. Nasza nowa konfiguracja pojawiła sie teraz w preferencjach tworzonego projektu.Jesli tak sie nie stanie, wybieramy ja z rozwijalnej listy.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 68

Powinnismy wrócic do pierwszego okna. Nalezy wypełnic nazwe modułu. Jesli pojawi sie bładmówiacy o błedzie kompilacji, nalezy powtórzyc wszystkie kroki od poczatku, nie usuwajac zadnych ut-worzonych plików.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 69

Struktura nowego projektu powinna wygladac jak na obrazku ponizej:

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 70

4.4.2 Tworzenie Web Service z klas Javy (bottom-up WS)Ta czesc artykułu demonstruje, jak za pomoca pluginu WTP stworzyc Web Service. Zaczniemy od napisa-nia nowej klasy w Javie, a nastepnie w prosty sposób przerobimy ja na usługe dostepna w sieci. Nalezysprawdzic czy spełnione sa wszystkie wymagania (4.2) i czy projekt jest utworzony (4.4.1).

Tak jak w innych tutorialach, stworzymy serwis, który składa sie z kilku metod. Na poczatek stwórzmynowe pakiety: pierwszy o nazwie interfejs, który bedzie udostepniał na zewnatrz funkcje pakietu imple-mentacja. Aby utworzyc pakiet, nalezy kliknac prawym przyciskiem myszki na nazwie projektu (Serwis)i wybrac New->Package. Dotychczasowy wyglad przedstawia sie nastepujaco:

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 71

Utworzymy teraz nowe klasy (PPM na nazwie pakietu New->Class).Do pakietu implementacja nalezaklasy:

• Adres - klasa składa sie z dwóch pół nazwa i adres. Opisuje adres hosta

• Sieciowa - z metoda getIp(String host) , zwraca Adres

• Testowa - zawiera publiczne metody: podziel() i halo()

Do pakietu interfejs nalezy klasa

• InterfejsSerwisu - klasa która udostepnia na swiat metody getIP() i hello() - nie udostepnia natomiastpublicznej metody podziel()

Kod pakietu serwis pokazuja listingi

• klasa Adres

package implementacja;public class Adres{

public String nazwa;public String adres;private int tajemnica=-1;

}

• klasa Testowa

package implementacja;public class Testowa{

public String hello(){System.out.println("Tego nie bedzie widac");return "Hello World!";

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 72

}private String niedostepna(){

System.out.println("metody private nie da sie wywolac");return "halo";

}public float podziel(int a, int b){

return (float)a/b;}

}

• klasa Sieciowa

package implementacja;import java.net.InetAddress;public class Sieciowa{

public Adres getIP(String host){Adres adr = new Adres();adr.nazwa = host;java.net.InetAddress inetAdd = null;try{

inetAdd = java.net.InetAddress.getByName(host);}catch(java.net.UnknownHostException uhe){}adr.adres = inetAdd.getHostAddress();return adr;

}}

• klasa InterfejsSerwisu

package interfejs;import implementacja.Adres;public class InterfejsSerwisu{

public Adres getIP(String host){Sieciowa s = new Sieciowa();return s.getIP(host);

}

public String hello(){Testowa t = new Testowa();return t.hello();}

}

Teraz udostepnimy WS na zewnatrz. Nalezy kliknac PPM plik InterfejsSerwisu.java i wybrac New ->Other... -> Web Services -> Web Service.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 73

Otworzy sie okno, w którym wybieramy interesujace nas opcje. Sa to:

• Start Web Service in Web Project - tworzy klasy odpowiedzialne za udostepnianie Web Service

• Overwrite files without warning - zastepuje pliki z poprzedniego udostepniania

Sa tutaj jeszcze inne, ciekawe opcje, jednak jak w tym momencie nie zawsze działaja.

• Generate a proxy - tworzy proxy przez które mozna połaczyc sie z WS w celach testowych

• Monitor the Web service - pokazuje komunikaty SOAP jakie wchodza do i wychodza z serwisu

• Test the Web service - zostanie utworzony pseudoklient, za pomoca którego mozna podejrzec dzi-ałanie WS

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 74

Klikamy Next. Pokaze sie wybrana przez nas klasa

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 75

Klikamy Next i widzimy konfiguracje serwera:

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 76

Wszystko jest jak powinno byc, mozemy kliknac Finish. Rozpocznie sie przetwarzanie (w tym tworze-nie pliku WSDL) i kompilacja naszego projektu, a nastepnie uruchamianie serwera. Po zakonczeniu, nadole ekranu powinna pojawic sie zakładka z serwerami (jesli nie, nalezy kliknac servers). Pokaze sie listauruchomionych serwerów:

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 77

Klikajac PPM na nazwie serwera i wybierajac Add and remove Projects mozemy kontrolowac odpalonena serwerze aplikacje.

Przetestujmy zainstalowane usługi. W wyszukiwarce, pod adresem http://localhost:8080/serwer/services/InterfejsSerwisuznajduje sie nasz serwis. Adres tworzony jest według zasady

protokół://serwer:port/nazwaModułu/service/nazwaUdostepnionejKlasy

Zwyczajowo, dodajac ?wsdl na koncu otrzymamy plik WSDL (http://localhost:8080/serwer/services/InterfejsSerwisu?wsdl).Serwis mozna w danym momencie przetestowac na dwa sposoby: testowanie za pomoca URL (4.4.8)

lub uzycie narzedzia Web Services Explorer (4.4.7). Polecam ta druga metode.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 78

4.4.3 Tworzenie Web Service z pliku WSDL (top-down WS)Najpierw zamknijmy (PPM->Close Project) otwarte projekty. Teraz zbudujmy nowy projekt (opis: 4.4.1)o nazwie SerwerWSDL i nazwie modułu serwisWSDL.

Kod zostanie utworzony na podstawie dokumentu WSDL. Otwórzmy przegladarke na adresie z plikiemWSDL i zapiszmy go na dysku, pamietajac o nadaniu mu rozszerzenia WSDL. Teraz nalezy go zaimpor-towac do Eclipse, do katalogu serwisWSDL/WebContent. Robimy to klikajac PPM na katalogu WebCon-tent i wybierajac Import

Nastepnie wybieramy File System

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 79

Klikamy Next. W nowym okienku Browse i wybieramy katalog w którym jest plik WSDL, a nastepniez listy wybieramy ten plik.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 80

Klikamy finish. Plik powinien pojawic sie w strukturze katalogów

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 81

Teraz nalezy kliknac PPM na pliku WSDL i wybrac New->Other...->Web->Web Service. Tym razemwybierzemy Top down Java bean Web Service.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 82

Zeby zobaczyc opcje, nalezy klikac Next. My zaakceptujemy domyslne wartosci i klikniemy Finish.Po pewnym czasie, potrzebnym na generacje i uruchomienie serwera, zobaczymy strukture klas wygen-

erowana przez Eclipse.

Teraz nalezy wpisac kod, który zostanie wykonany przy wywołaniu odpowiednich metod. Zrobimy

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 83

to w pliku InterfejsSerwisuSoapBindingImpl.java. Zauwazmy, ze sa tutaj tylko dwie metody - te którewymienione zostały w pliku WSDL. Nalezy zmodyfikowac kod klasy, tak aby wygladała jak ponizszyalgorytm

package interfejs;public class InterfejsSerwisuSoapBindingImpl

implements interfejs.InterfejsSerwisu{public implementacja.Adres getIP(java.lang.String host)

throws java.rmi.RemoteException {implementacja.Adres adr = new implementacja.Adres();java.net.InetAddress inetAdd = null;try{

inetAdd = java.net.InetAddress.getByName(host);}catch(java.net.UnknownHostException uhe){}adr.setNazwa(host);adr.setAdres(inetAdd.getHostAddress());return adr;

}

public java.lang.String hello()throws java.rmi.RemoteException {

System.out.println("Tego nie bedzie widac");return "Hello WSDL!";

}

}

To juz koniec pracy - teraz mozna przetestowac (4.4.7 lub 4.4.8) nowo utworzony serwis. Jego adres tohttp://localhost:8080/serwisWSDL/services/InterfejsSerwisu .

4.4.4 Tworzenie klienta Web Service przy pomocy WTPZeby uczciwie pokazac działanie klienta, połaczymy sie ze zdalnym serwerem, na którym znajduje siejakas aplikacja. W naszym przypadku bedzie to wyeksportowana wczesniej (4.4.6) kopia naszego serwisu.Jezeli jednak nie ma mozliwosci uzywania innego komputera, mozna skorzystac z odpalonej kopii nalocalhost - klient nie bedzie uzywał “sztuczek” siegajac do lokalnych powiazan i skorzysta z niego jak zzewnetrznego serwera.

Na poczatek stwórzmy nowy projekt (4.4.1) o nazwie ProjektKlienta i module klient. Kod zostanie ut-worzony na podstawie dokumentu WSDL. Otwórzmy przegladarke na adresie z plikiem WSDL i zapiszmygo na dysku, pamietajac o nadaniu mu rozszerzenia WSDL. Teraz nalezy go zaimportowac do Eclipse, dokatalogu klient/WebContent. Robimy to klikajac PPM na katalogu WebContent i wybierajac Import.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 84

Nastepnie wybieramy File System

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 85

Klikamy Next. W nowym okienku Browse i wybieramy katalog w którym jest plik WSDL, a nastepniez listy wybieramy ten plik.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 86

Klikamy finish. Plik powinien pojawic sie w strukturze katalogów

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 87

Teraz mozemy przystapic do tworzenia aplikacji. W Package Explorer nalezy kliknac PPM na zaim-portowanym pliku InterfejsSerwisu.wsdl w katalogu WebContent i wybrac New -> Other... -> Web Services-> Web Service Client. Nastepnie kliknac Next i wybrac Overwrite files without warning. Wybierzmy tezopcje Test Web Service, która sprawi, ze zostanie równiez utworzony proxy, przez który bedziemy moglisprawdzic jak działa klient.

Po wygenerowaniu klas odpowiedzialnych za łaczenie sie z serwerem, uruchomiona zostanie przegla-darka z testowym klientem. Jezeli okienko nie otworzy sie samoczynnie, mozna wejsc przez adres http://localhost:8080/klient/sampleInterfejsSerwisuProxy/TestClient.jsp

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 88

Tutaj, klikajac nazwy metody, a nastepnie Invoke, mozna wywoływac mechanizmy zdalnego serwera.Kod tego proxy znajduje sie w katalogu klient/WebContent/sampleInterfejsSerwisuProxy.

Trzeba zauwazyc, ze najwazniejszymi plikami nie sa te z proxy, ale te w pakietach interfejs i imple-mentacja

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 89

To one odpowiadaja za połaczenie. Spróbujmy teraz recznie stworzyc testowego klienta.

4.4.5 Klasa wykorzystujaca wygenerowany kod klienta (klient statyczny)Stworzymy od podstaw kod klienta, który połaczy sie z serwerem za pomoca klasy interfejs/InterfejsSerwisuServiceLocator.java.Nie bedzie on wymagał działajacego serwera.

Umiescimy go w osobnym pakiecie klient (PPM na folderze klient/JavaSource, New->Package...->klient), klase nazwiemy Klient (PPM na pakiecie klient New->Class->...>Klient). Pełen kod klientawyglada nastepujaco:

package klient;

import implementacja.Adres;import interfejs.InterfejsSerwisu;import interfejs.InterfejsSerwisuService;import interfejs.InterfejsSerwisuServiceLocator;import java.rmi.RemoteException;import javax.xml.rpc.ServiceException;

public class Klient {public static void main(String[] args)

throws ServiceException, RemoteException {String host=null;InterfejsSerwisuService locator =

new InterfejsSerwisuServiceLocator();InterfejsSerwisu service =

locator.getInterfejsSerwisu();System.out.println("Metoda Hello odpowiada nam: " +

service.hello());if (args.length == 1)

host = args[0];else

host = "vercom.pl";Adres adr = new Adres();adr = service.getIP(host);System.out.println("Adres hosta "+

adr.getNazwa() +" to "+adr.getAdres());

}

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 90

}

Trzeba zaimportowac wszystkie klasy z pakietu Serwis a takze klase Adres. Klient posiada tylko funkcjemain(). Własciwie tylko dwie linie wymagaja komentarza:

InterfejsSerwisuService locator =new InterfejsSerwisuServiceLocator();

InterfejsSerwisu service =locator.getInterfejsSerwisu();

Te dwie linie najpierw tworza obiekt, a potem za jego pomoca ustawiaja odpowiednie połaczenia (klasa In-terfejsSerwisuSoapBindingStub) i tworza interfejs, który umozliwia bezposrednie połaczenie z serwerem.

Pozostałe linie to juz wywołanie odpowiednich funkcji na serwerze: hello() i getIP() z parametrempodanym w linii polecen.

Aby uruchomic klienta, nalezy kliknac PPM klase Klient, a nastepnie wybrac Run As->Run. Ustawieniepowinno wygladac nastepujaco:

W zakładce Arguments podajemy argumenty

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 91

Klikamy Run. Rezultatem jest:

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 92

4.4.6 Web Service na zdalnym serwerze (eksport projektu do pliku WAR)Niestety w obecnej wersji, WST nie posiadaja mozliwosci zdalnego udostepniania aplikacji (zdalnym ser-werze czyli na innym niz localhost). Jednak mozliwe jest wyeksportowanie całego serwisu do pliku WAR,który moze zostac wgrany na zdalny serwer. Warunkiem jest wczesniejsze utworzenie pliku WSDL. Dziejesie to automatycznie przy tworzeniu Web Service (opis w punkcie 4.4.2).

Aby wyeksportowac serwis, nalezy kliknac PPM na nazwie serwisu i wybrac Export

Z listy wybieramy WAR file

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 93

Wybieramy nazwe modułu i podajemy do jakiego pliku eksportowac. Nastepnie klikamy Finish. Wkatalogu docelowym pojawi sie plik z naszym serwisem.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 94

Teraz wystarczy wgrac plik na zdalny serwer. My zrobimy to uzywajac Apache Tomcat Manager naserwerze umieszczonym na innym komputerze w sieci lokalnej (konieczna jest równiez instalacja Axisa).

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 95

Po zalogowaniu sie widzimy miedzy innymi liste juz uruchomionych usług

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 96

Interesujaca nas czescia jest ta dotyczaca plików WAR. Wprowadzamy tam nasz plik

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 97

Nastepnie klikamy “Deploy”. Jezeli poszło dobrze, aplikacja pojawi sie na liscie

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 98

Za pomoca kontrolek mozna ja kolejno: wystartowac, zatrzymac, przeładowac, usunac. Własciwa ap-likacja znajduje sie pod adresem http://192.168.1.33:8080/serwer/services/InterfejsSerwisu .Przetestujmy ja podajac jej spreparowany URL http://192.168.1.33:8080/serwer/services/InterfejsSerwisu?method=hello :

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 99

Jak widac, wszystko działa poprawnie. Zachecam do przetestowania za pomoca Web Services Explorer(4.4.7).

4.4.7 Testowanie WS uzywajac Web Services ExplorerOpublikowany na serwerze Web Service mozna przetestowac. Test polega na podaniu argumentów metodi obserwowanie wyników przez nie zwróconych. Przetestujmy nasz przykładowy serwis, znajdujacy siepod adresem http://localhost:8080/serwer/services/InterfejsSerwisu .

Na poczatek z menu Run wybieramy Launch the Web Services Explorer. Explorer otworzy sie w oknieEclipse lub w nowym oknie. Nalezy kliknac ikonke WSDL Explorer (to ta kolorowa w prawym górnymrogu okna).

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 100

Explorer przełaczy sie w tryb WSDL z trzema panelami: Navigator, Actions i Status. Po kliknieciu nalink WSDL Main w Nawigatorze, w oknie Action pojawi sie miejsce do wpisania linku. Wpiszemy tamadres do WSDL naszego serwisu i klikniemy Go.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 101

Nasz serwis zostanie wczytany i pokaze sie lista dostepnych metod (hello() i getIP() ), a takze adresserwisu. Kliknijmy na metode hello().

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 102

Pokazał sie panel wywołania metody hello(). Nie przyjmuje ona zadnych argumentów, dlatego wystar-czy nacisnac Go.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 103

W okienku Status pojawiła sie odpowiedz naszego serwisu: HelloWorld! Jezeli teraz zerkniemy nazakładke Console w Eclipse, zobaczymy komunikat wypisany na stdout w metodzie hello(): “Tego niebedzie widac”.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 104

Kiedy klikniemy na link Source w okienku Actions, zobaczymy komunikat SOAP który został wysłanydo serwera.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 105

Jesli natomiast klikniemy na link Source w okienku Status, zobaczymy komunikat SOAP który zostałwygenerowany w odpowiedzi.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 106

Przetestujmy teraz metode getIP(). Kliknijmy na jej nazwe w Nawigatorze.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 107

Pod adresem mozna teraz wpisac parametr: nazwe hosta. Wpiszmy tam “vercom.pl” i kliknijmy Go.Wynikiem działania jest nazwa i adres IP serwera - czyli dokładnie to czego oczekiwalismy.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 108

Spróbujmy teraz podejrzec zródło odpowiedzi

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 109

Tak wiec udało sie nam przetestowac nasz serwis za pomoca Service Explorera.

4.4.8 Testowanie Web Service za pomoca URLWywoływanie przez URL to metoda ograniczona, stojaca w zasadzie w sprzecznosci z idea Web Services,powinna słuzyc tylko celom testowym. Lepszym sposobem jest uzycie narzedzia Web Services Explorer(4.4.7)

Wywołanie za pomoca URL polega na wpisaniu odpowiednio sformatowanego adresu.

ROZDZIAŁ 4. WEB SERVICES Z UZYCIEM ECLIPSE WEB TOOLS PLATFORM 110

http://localhost:8080/sciezka/sciezka2/NazwaSerwisu?op1=wart1&op2=wart2&op3=wart3

Interesowac beda nas w zasadzie tylko nastepujace opcje:

• ?wsdl wyswietla plik WSDL

• ?method=hello - okresla nazwe metody do wywołania (hello)

• ?method=hello&arg1=2&arg2=4 - wywołuje funkcje hello z argumentem o nazwie arg1 i wartosci2 oraz argumentem o nazwie arg2 i wartosci 4. Kolejnosc nie jest wazna, nazwy argumentów tak.

4.5 Pliki do pobraniaWszystkie uzyte w tym artykule kody zródłowe znalezc mozna pod adresem pliki/eclipse-zrodla.zip .Znajduja sie tam utworzone na kazdym etapie pliki WAR (opcja wraz z kodami zródłowymi) jak równiezbezposrednie kopie katalogu workspace Eclipse.

Rozdział 5

Web Services i Googletworzenie klienta

5.1 WstepW tym artykule zostanie opisany sposób, w jaki mozna połaczyc sie z publicznie dostepnym serwisemstworzonym przez Google. Oferuje on wyszukiwanie w katalogu stron, a takze kilka interesujacych rzeczy(np. odczytanie Google Rank danej strony). Wykorzystamy w tym celu Jave i Axisa (5.3), a takze PHPwraz z jego rozszerzenie SOAP (5.4).

Pierwszym krokiem, zanim przystapimy do kodowania, jest zarejestrowanie sie w programie GoogleAPI https://www.google.com/accounts/NewAccount?continue=http://api.google.com/createkey&followup=http://api.google.com/createkey .Udział w nim jest bezpłatny, wystarczy tylko posiadac konto mailowe. Rejestrujac sie otrzymamy klucz li-cencyjny (w listingach na tej stronie klucz musi zastapic wyrazenie KLUCZ_OTRZYMANY_OD_GOOGLE), dzieki któremu nawiazemy połaczenie z serwerem. Pobierzmy równiez Google Web APIs Developer’sKit ze strony http://www.google.com/apis/download.html . Sciagniety plik rozpakujmy. W struk-turze katalogów znajdziemy zarówno dokumentacje, jak i plik wsdl, a takze gotowe klasy Javy słuzace dopołaczenia z Google.

5.2 Uzycie dostarczonych bibliotekJuz teraz, za pomoca bibliotek sciagnietych z sieci, mozemy przeprowadzic przykładowe poszukiwania.Wydajmy polecenie

java -cp googleapi.jar com.google.soap.search.GoogleAPIDemo \KLUCZ_OTRZYMANY_OD_GOOGLE search linux

Odpowiedz systemu wyglada nastepujaco:

Parameters:Client key = KLUCZ_OTRZYMANY_OD_GOOGLEDirective = searchArgs = linuxGoogle Search Results:======================{TM = 0.296994Q = "linux"CT = ""TT = ""

111

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 112

CATs ={{SE="", FVN="Top/Computers/Software/Operating_Systems/Linux"}}

Start Index = 1End Index = 10Estimated Total Results Number = 31500000Document Filtering = falseEstimate Correct = falseRs ={[URL = "http://www.linux.org/"Title = "The <b>Linux</b> Home Page at <b>Linux</b> Online"Snippet = "Comprehensive information and resources about the

<b>Linux</b> Operating System."Directory Category = {SE="",FVN="Top/Computers/Software/Operating_Systems/Linux/Directories"}

Directory Title = "<b>Linux</b>.org"Summary = "Comprehensive information and resources about the <b>Linux</b>Operating System."

Cached Size = ""Related information present = trueHost Name = "www.linux.org"],

.....

Jak widac, udało sie nam połaczyc z wyszukiwarka i nakazac jej wykonac polecenie. Jednak w tensposób nasze mozliwosci sa ograniczone do prostego wyszukiwania lub wykonywania innych funkcji za-planowanych z góry przez Googla. Spróbujemy wiec sami napisac klienta od podstaw. Damy mu bardziejzaawansowane zadanie: niech sprawdza, które miejsce w rankingu google zajmuje wybrana przez nasstrona. Do tego potrzebne beda słowa kluczowe, według których chcemy tworzyc ranking, oraz adresstrony która chcemy sprawdzic.

5.3 Klient JavaPotrzebna nam jest znajomosc metod, które udostepnia ten Web Service. Mozna je wszystkie poznac czyta-jac plik WSDL, jednak skoro w tym przypadku istnieje dokumentacja (http://www.google.com/apis/reference.html),skorzystajmy z niej - jest ona bardziej szczegółowa. Teraz mozemy przejsc do tworzenia aplikacji.

Jak juz napisano, aplikacja ma sprawdzac pozycje strony w wyszukiwarce. W tym celu potrzebne sasłowa kluczowe, według których szukamy oraz adres strony która obserwujemy. Wykorzystamy tu prostazasade porównywania strony znalezionej z szukana: jesli wpiszemy adres vercom.pl jako ten, który nasinteresuje, to sukces osiagniemy trafiajac przykładowo na wpis http://www.vercom.pl/ws lub nawethttp://webservices.vercom.pl/ws . Przejdzmy teraz do pisania programu.

Utwórzmy nowy projekt WS w Eclipse i zaimportujmy (Import->File System-> GoogleSearch.wsdl) doniego dostarczony plik .wsdl. Mozemy równiez skorzystac z pliku pod adresem http://api.google.com/GoogleSearch.wsd .Nastepnie utwórzmy z tego pliku klienta (PPM na nazwie pliku, New->Other->Web->WS Client).

W katalogu JavaSource pojawiły sie pliki do słuzace do połaczenia z Google. Utwórzmy nowy pakietklient z klasa KlientGoogle. Klasa zawierac bedzie tylko funkcje main(), która uruchomi sie i rozpoczniewyszukiwanie, wypisujac wyniki na stdout. Musimy zaimportowac potrzebne pliki (wygenerowane z plikuWSDL).

import GoogleSearch.GoogleSearchPort;import GoogleSearch.GoogleSearchResult;import GoogleSearch.GoogleSearchService;

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 113

import GoogleSearch.GoogleSearchServiceLocator;import GoogleSearch.ResultElement;

Nastepnie zostana wypisane komunikaty i ustawione zmienne według których szukamy:

String key = "KLUCZ_OTRZYMANY_OD_GOOGLE";String slowaKluczowe = "szukaj";int maksPozycja = 100;int pozycja =0;String podanyAdres="szukacz.pl";String obecnyAdres=null;System.out.println( "Witamy w systemie sprawdzania" +" rankingu google!\n" +"Szukana strona: \t" + podanyAdres+ "\n"+"Maksymalna pozycja:\t" + maksPozycja + "\n"+"Slowa kluczowe:\t\t" + slowaKluczowe+ "\n\n");

Waznym momentem jest połaczenie z wygenerowanymi klasami:

GoogleSearchService service =new GoogleSearchServiceLocator();

GoogleSearchPort gsPort =service.getGoogleSearchPort();

GoogleSearchResult result =new GoogleSearchResult();

ResultElement[] wyniki = null;

Teraz nastapi najwazniejszy z widzenia uzytkownika moment, czyli skorzystanie z mozliwosci GoogleAPIs. W pliku WSDL widzimy fragment

<message name="doGoogleSearch"><part name="key" type="xsd:string"/><part name="q" type="xsd:string"/><part name="start" type="xsd:int"/><part name="maxResults" type="xsd:int"/><part name="filter" type="xsd:boolean"/><part name="restrict" type="xsd:string"/><part name="safeSearch" type="xsd:boolean"/><part name="lr" type="xsd:string"/><part name="ie" type="xsd:string"/><part name="oe" type="xsd:string"/></message>

Elementy, które tu widzimy, zostały objasnione na stronie http://www.google.com/apis/reference.html#searchrequest .Najwazniejsze sa pierwsze cztery:

• key - klucz który otrzymalismy przy rejestracji

• q - zapytanie (słowa kluczowe)

• start - od której strony chcemy otrzymac rezultaty (rezultaty sa podzielone na stron, zawierajacelinki 1-10, 11-20, 21-30....)

• maxResults - ile chcemy otrzymac wyników. Maksymalna wartosc to 10

Nasz serwis bedzie szukał az osiagnie strone o numerze maksPozycja lub tez odnajdzie zadana strone. Jed-nak Google pozwala na pobranie tylko 10 wyników naraz. Dlaczego trzeba stworzyc petle, która bedzie pokolei pobierała po 10 wyników z kolejnych stron. Do polecenia wyszukiwania podajemy kolejno wszystkieargumenty pokazane w pliku WSDL (5.3).

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 114

for (int i=0; i<maksPozycja/10; i++){result = gsPort.doGoogleSearch(key,

slowaKluczowe, i*10, 10, true, "countryPL",false, "lang_PL", "UTF-8", "UTF-8");

Wywołanie zapytania wyglada nastepujaco:

wyniki = result.getResultElements();

Teraz sprawdzimy, czy wsród dziesiatki otrzymanych rezultatów znajduje sie interesujaca nas strona.Wykonamy petle

for (int j=0; j<10; j++){pozycja = i*10 + j + 1;

Pobierzemy teraz adres kazdego z wyników. Inne mozliwosci opisano na stronie http://www.google.com/apis/reference.html#3_2(miedzy innymi getSnippet() - pobierz opis, getTitle() - tytuł strony)

obecnyAdres = wyniki[j].getURL();System.out.println("Pozycja "+pozycja+

" adres " + obecnyAdres);

Jesli znajdziemy szukana strone, wypisujemy komunikat i konczymy.

if (obecnyAdres.contains(podanyAdres)){System.out.println(

"\n\nTwoja strona jest na "+pozycja + " miejscu.\n Adres: "+obecnyAdres );

return;}

}}

Udało nam sie stworzyc od podstaw, korzystajac tylko z pliku WSDL i WTP pod Eclipse klienta usługiGoogle APIs. Pełen kod klasy KlientGoogle wyglada nastepujaco:

package klient;import GoogleSearch.GoogleSearchPort;import GoogleSearch.GoogleSearchResult;import GoogleSearch.GoogleSearchService;import GoogleSearch.GoogleSearchServiceLocator;import GoogleSearch.ResultElement;public class KlientGoogle {

public static void main(String[] args) {String key = "KLUCZ_OTRZYMANY_OD_GOOGLE";String slowaKluczowe = "szukaj";int maksPozycja = 100;int pozycja =0;String podanyAdres="szukacz.pl";String obecnyAdres=null;System.out.println( "Witamy w systemie sprawdzania" +" rankingu google!\n" +"Szukana strona: \t" + podanyAdres+ "\n"+"Maksymalna pozycja:\t" + maksPozycja + "\n"+

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 115

"Slowa kluczowe:\t\t" + slowaKluczowe+ "\n\n");

try{GoogleSearchService service =

new GoogleSearchServiceLocator();GoogleSearchPort gsPort =

service.getGoogleSearchPort();GoogleSearchResult result =

new GoogleSearchResult();ResultElement[] wyniki = null; ;

for (int i=0; i<maksPozycja/10; i++){result =gsPort.doGoogleSearch(

key, slowaKluczowe, i*10, 10, true,"countryPL",false,"lang_PL", "UTF-8", "UTF-8");wyniki = result.getResultElements();

for (int j=0; j<10; j++){pozycja = i*10 + j + 1;obecnyAdres = wyniki[j].getURL();System.out.println("Pozycja "+pozycja+

" adres " + obecnyAdres);if (obecnyAdres.contains(podanyAdres)){

System.out.println("\n\nTwoja strona jest na "+pozycja + " miejscu.\n Adres: "+obecnyAdres);

return;}

}}System.out.println("Twoja strona nie znalazla sie " +

"posrod pierwszych "+ maksPozycja);}catch ( Exception e ){

System.out.println("Exception" + e );}

}}

5.4 Klient w PHPWykorzystamy rozszerzenie PHP pozwalajace na uzycie protokołu SOAP. Dodawane jest ono do PHP wwersji 5.0.

Stworzymy prosty formularz HTML, gdzie wpiszemy słowa kluczowe, adres docelowej strony i iloscwyników do przeszukania.

<form method="POST" target="<?php echo $PHP_SELF; ?>">Slowa kluczowe <input name="slowaKluczowe" type="text"><br />Szukana strona <input name="podanyAdres" type="text"><br />Maksymalna pozycja <input name="maksPozycja" type="text"><br /><input type="submit" value="Wyslij" />

</form>

Teraz czas na czesc w PHP. Napiszemy funkcje, która przyjmie trzy parametry podane przez formularz iwyszuka potrzebne nam wiadomosci. Stworzenie klienta odbywa sie za pomoca polecenia

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 116

$soapclient = new SoapClient(’http://api.google.com/GoogleSearch.wsdl’);

Teraz wystarczy tylko wywołac odpowiednia metode. W samym wyszukiwaniu, podobnie jak w kliencieJava, podajemy parametry za pomoca argumentów:

$odpowiedz = $soapclient->doGoogleSearch($key, $slowaKluczowe, $i*10, 10,

true, ’countryPL’, false, ’lang_PL’, ”,”);

Równiez do wyników odwołujemy sie przez pola klasy:

$obecnyAdres = $odpowiedz->resultElements[$j]->URL;

Po dokładniejszy opis mozliwych do odczytania wyników zapraszam pod adres http://www.google.com/apis/reference.html .Nasz serwis prezentuje sie i działa nastepujaco:

Kompletny kod klienta prezentuje sie nastepujaco:

<html><body>

<form method="POST" target="<?php echo $PHP_SELF; ?>">Slowa kluczowe <input name="slowaKluczowe" type="text"><br />Szukana strona <input name="podanyAdres" type="text"><br />Maksymalna pozycja <input name="maksPozycja" type="text"><br /><input type="submit" value="Wyslij" />

</form><?phpif ($slowaKluczowe != "")

szukaj($slowaKluczowe, $maksPozycja, $podanyAdres);function szukaj($slowaKluczowe, $maksPozycja, $podanyAdres){

$key = "KLUCZ_OTRZYMANY_OD_GOOGLE";$pozycja = 0;$obecnyAdres=null;

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 117

$soapclient = new SoapClient(’http://api.google.com/GoogleSearch.wsdl’);for ($i=0; $i<$maksPozycja/10 ; $i++){

$odpowiedz = $soapclient->doGoogleSearch($key,$slowaKluczowe,$i*10,10,true,’countryPL’,false,’lang_PL’,”,”);

for ($j=0; $j<10; $j++){$pozycja = $i*10 + $j + 1;$obecnyAdres = $odpowiedz->resultElements[$j]->URL;print "Pozycja $pozycja:

<a href=\"$obecnyAdres\">$obecnyAdres</a><br>";if (strpos($obecnyAdres, $podanyAdres) === false)

;//nie rob nicelse

exit("Twoja strona znalazla sie na $pozycja miejscu.");}

}exit("Twoja strona niestety nie znalazla sie wsrod \

pierwszych $maksPozycja miejsc.");}?>

</body></html>

Nie wszystkie implementacje SOAP pod PHP działaja tak “klasowo”. Wystarczy porównac tego samegoklienta napisanego za pomoca klasy nusoap. (http://prdownloads.sourceforge.net/nusoap/nusoap-0.7.2.zip?download),widocznego na listingu ponizej, gdzie odwołanie do wyniku nastepuje za pomoca tablicy:

$obecnyAdres = $odpowiedz["resultElements"][$j]["URL"];

Warto równiez zwrócic uwage na przekazywanie parametrów za pomoca tablicy asosjacyjnej:

for ($i=0; $i<$maksPozycja/10; $i++){$params = array(

’key’ => $key,’q’ => $slowaKluczowe,’start’ => $i*10,’maxResults’ => 10,’filter’ => true,’restrict’ => ’countryPL’,’safeSearch’ => false,’lr’ => ’lang_PL’,’ie’ => ’UTF-8’,’oe’ => ’UTF-8’);

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 118

Klient z biblioteka nusoap

<html><body>

<form method="POST" target="<?php echo $PHP_SELF; ?>">Slowa kluczowe <input name="slowaKluczowe" type="text"><br />Szukana strona <input name="podanyAdres" type="text"><br />Maksymalna pozycja <input name="maksPozycja" type="text"><br /><input type="submit" value="Wyslij" />

</form><?phprequire_once(’nusoap.php’);if ($slowaKluczowe != "")

szukaj($slowaKluczowe, $maksPozycja, $podanyAdres);function szukaj($slowaKluczowe, $maksPozycja, $podanyAdres){

$key = "KLUCZ_OTRZYMANY_OD_GOOGLE";$pozycja = 0;$obecnyAdres=null;$soapclient = new soapclient(

’http://api.google.com/GoogleSearch.wsdl’,’wsdl’);

$soapoptions = ’urn:GoogleSearch’;for ($i=0; $i<$maksPozycja/10; $i++){

$params = array(’key’ => $key,’q’ => $slowaKluczowe,’start’ => $i*10,’maxResults’ => 10,’filter’ => true,’restrict’ => ’countryPL’,’safeSearch’ => false,’lr’ => ’lang_PL’,’ie’ => ’UTF-8’,’oe’ => ’UTF-8’);

$odpowiedz = $soapclient->call(’doGoogleSearch’,$params,

’urn:GoogleSearch’,’urn:GoogleSearch’);

for ($j=0; $j<10; $j++){$pozycja = $i*10 + $j + 1;$obecnyAdres = $odpowiedz["resultElements"][$j]["URL"];print "Pozycja $pozycja:

<a href=\"$obecnyAdres\">$obecnyAdres</a><br>";if (strpos($obecnyAdres, $podanyAdres) === false)

;//nie rob nicelse

exit("Twoja strona znalazla sie na $pozycja miejscu.");}

}exit("Twoja strona niestety nie znalazla sie wsrod \

pierwszych $maksPozycja miejsc.");}

ROZDZIAŁ 5. WEB SERVICES I GOOGLE TWORZENIE KLIENTA 119

?></body>

</html>

Trzeba jednak pamietac, ze pakiet nusoap powoduje konfilkt z rozszerzeniem PHP-SOAP, nalezy wiecodinstalowac rozszerzenie jesli chce sie uzywac tej klasy.

5.5 Pliki do pobraniaWszystkie uzyte w tym artykule kody zródłowe znalezc mozna pod adresem pliki/google-zrodla.zip.Znajduje sie tam utworzony z projektu WTP plik WAR (opcja wraz z kodami zródłowymi) oraz pliki PHP.

Rozdział 6

Dodatki

6.1 Słowniczek

6.1.1 XMLXML (ang. Extensible Markup Language) - wzorowany na SGML-u sposób opisu znacznikami, umozli-wiajacy wygodniejsze, szybsze i mniej sformalizowane przygotowywanie wszelkich dokumentów tekstowo-graficznych, które mozna bez wiekszych problemów przenosic i adaptowac do róznych form przekazuelektronicznego.

XML to jezyk znaczników umozliwiajacy podobnie jak SGML tworzenie swoich własnych znacznikówformatujacych definiowanych w DTD dokumentu lub w tzw. schematach XML. W odróznieniu od SGML-a mozliwe jest jednak takze stosowanie w XML-u kaskadowych arkuszy stylów CSS, programowalnycharkuszy stylów specjalnie zaprojektowanych dla XML-a o nazwie XSL i innych interaktywnych elementówczesto stosowanych przy pisaniu stron WWW.

XML wymaga znacznie wiekszej dyscypliny przy pisaniu dokumentów niz HTML, gdyz zasada in-terpretacji XML-a jest najpierw kontrola poprawnosci składniowej a dopiero pózniej ew. wyswietle-nie/wykonanie dokumentu, tak wiec błednie napisane dokumenty XML nie beda w ogóle wyswietlaneprzez przegladarki. Z drugiej jednak strony, dzieki restrykcyjnej składni, dokumenty XML moga byc au-tomatycznie przekształcane na inne formaty jezyków, przez programy zwane parserami.

XML i jego zastosowania prawdopodobnie w przyszłosci zastapia całkowicie HTML, gdyz XML wwersji 1.0 został uznany za standard przez W3C i jego rozwój jest silnie wspierany przez prawie wszystkienajwazniejsze firmy produkujace oprogramowanie, takie jak: Microsoft, Oracle, Silicon Graphics, SunMicrosystems, Netscape i wiele innych. Od 4 lutego 2004 r. najnowsza wersja XML jest XML 1.1, któraw porównaniu do XML 1.0 jest bardziej elastyczna pod wzgledem stosowania róznych znaków standarduUnicode.

XML jest jednak czyms znacznie wiecej niz HTML gdyz umozliwia pisanie dokumentów, które bedamogły byc obsługiwane przez najrózniejsze urzadzenia i programy. XML umozliwia tez tworzenie tzw.aplikacji - czyli zestawów znaczników do konkretnych zastosowan, z których obecnie najbardziej znanesa: XHTML, MathML, SVG, ChemXL. Zaleta XML-a jest mozliwosc dowolnego mieszania tych aplikacji,co umozliwia np. właczanie fragmentów MathML czy SVG w dokumenty napisane w XHTML-u, tworzacjeden, poprawny składniowo dokument XML.

Z XML wiaza sie nierozerwalnie jezyki XML Namespaces, XML Base, XLink i XInclude.Obecnie wiekszosc przegladarek WWW nie obsługuje jeszcze bezposrednio XML-a (choc czesciowo

jest juz on obsługiwany przez Internet Explorer 6 oraz Opere i przegladarki oparte na Gecko, np. Mozilla),ale mozliwe jest juz pisanie stron w XML-u, gdyz istnieja parsery tłumaczace XML na HTML lub XHTMLpod warunkiem przestrzegania pewnych podstawowych reguł pisania dokumentu w XML.

<?xml version="1.1"?><?xml-stylesheet type="text/css" href="#identyfikator"

title="instrukcja przetwarzania"?>

120

ROZDZIAŁ 6. DODATKI 121

<!DOCTYPE przyklad [<!ELEMENT przyklad (#PCDATA)><!-- komentarz --><przyklad atrybut="wartosc" xmlns="http://przestrzen.nazw.pl">

To jest przykład.<![CDATA[<znacznik>Sekcja CDATA</znacznik>]]>

</przyklad>

(Z Wikipedii, wolnej encyklopedii.)

6.1.2 J2EEJ2EE (Sun Microsystem Java 2 Platform, Enterprise Edition) - definiuje standard tworzenia aplikacji opar-tych na architekturze wielowarstwowej. J2EE wykorzystuje jezyk Java jako podstawe programowanialogiki aplikacji oraz definiuje srodowisko wykonania i model aplikacji. Stosowana technologia komponen-towa jest EJB (Enterprise Java Beans). Klient kupujacy rozwiazanie oparte na J2EE ma dowolny wybórjezeli chodzi o platforme sprzetowa, system operacyjny lub serwer aplikacji.

J2EE jest architektura wielowarstwowa. J2EE jest podzielona na logiczne czesci, izoluje warstwe logikiaplikacji od srodowiska wykonania. (Z Wikipedii, wolnej encyklopedii)