2006 03 XFire w akcji [Inzynieria Oprogramowania]

background image

48

Inżynieria

oprogramowania

www.sdjournal.org

Software Developer’s Journal 3/2006

XFire w akcji

W

ebserwisy okazały się długo oczekiwaną

odpowiedzią na potrzebę komunikacji po-

między rozproszonymi systemami tworzo-

nymi na różnych platformach i przy użyciu różnorod-

nych języków programowania. Dzięki użyciu powszech-

nie akceptowanych standardów bazujących na języku

XML (SOAP, WSDL,UDDI), możliwa stała się wymia-

na informacji oraz usług nie tylko pomiędzy aplikacja-

mi działającymi na platformach J2EE i Microsoft .NET,

ale także napisanymi praktycznie w dowolnym języku

jak C++, Pascal, Cobol ,a nawet językami skryptowymi

jak Perl, Python czy PHP.

Nie bez znaczenia także dla tak szybkiego rozwo-

ju tej technologii jest fakt, iż webserwisy są luźno po-

wiązane z aplikacją, której logikę udostępniają, tzn. ich

obecność praktycznie nie wpływa na istniejące kom-

ponenty, umożliwiając stopniowe, fragment po frag-

mencie, integrowanie ich z istniejącą funkcjonalnością.

Dzięki takiemu podejściu udostępnienie istniejącej logi-

ki za pomocą webserwisów możliwe jest bez ponosze-

nia dużych nakładów na modyfikacje aplikacji oraz ze

zminimalizowanym ryzykiem niepowodzenia.

Dzięki tym cechom webserwisy umożliwiają zinte-

growanie praktycznie dowolnych aplikacji, w jeden du-

ży rozproszony system, eliminując często konieczność

wprowadzania niezwykle kosztownych w utrzymaniu

systemów pośrednich, dopasowujących metody komu-

nikacji poszczególnych aplikacji. Duże korporacje zwią-

zane z internetem dość szybko dostrzegły możliwości

płynące z wykorzystania webserwisów i rozpoczęły

udostępnianie swoich usług z wykorzystaniem tej tech-

nologii. Do takich firm zaliczają się miedzy innymi: Go-

ogle, Amazon, Ebay,Yahoo oraz Allegro.

O poziomie zainteresowania wykorzystaniem tej

technologii może świadczyć fakt, iż w chwili obecnej

50,000 programistów zarejestrowanych jest w progra-

mie webserwisów firmy Amazon. Firma eBay może po-

chwalić się natomiast 8.000 firm oraz indywidualnych

programistów biorących udział w jej programie oraz

600 aplikacjami wykorzystującymi jej API, generujący-

mi około 40% wszystkich transakcji.

Problemy

z dostępnymi narzędziami

Przeszukując zasoby sieci internet bez trudu moż-

na znaleźć narzędzia ułatwiające tworzenie web-

serwisów, wymieniając chociażby najbardziej po-

pularne:

• JAX-WS oraz JAX-RPC firmy Sun:

http://java.sun.com/webservices/jwsdp/index.jsp,

• Axis 1.x

http://ws.apache.org/axis,

• XFire

http://xfire.codehaus.org,

• WASP:

http://www.systinet.com/products/systinet_server,

• WebLogic Web Services

http://e-docs.bea.com/wls/docs81/webserv/

Jednak wybranie odpowiedniego programu spełnia-

jącego naszego oczekiwania, nie jest sprawą prostą.

Każdy z nich umożliwia wyeksponowanie logiki naszej

aplikacji jako webserwisu, jednak również każdy z nich

posiada pewne wady, które mogą zniechęcić lub nawet

uniemożliwić jego użycie. Na początku należy więc za-

stanowić się jakie cechy powinno posiadać narzędzie

z którym będziemy pracować:

• łatwość użycia – dzięki czemu skróci się czas po-

trzebny na stworzenie aplikacji,

• wysoka wydajność – dzięki czemu będziemy mo-

gli obsłużyć większą ilość użytkowników bez ko-

nieczności dokupowania kolejnych kosztownych

serwerów,

Tomasz Sztelak

Autor od 2002r. tworzy aplikacje oparte na platformie
J2EE dla sektora bankowego. Jest również członkiem
zespołu tworzącego bibliotekę XFire.
Kontakt: tsztelak@gmail.com

Rysunek 1.

Architektura webserwisów

���������

�������

�����������

������

���������

�������

������������

�������

����

���������

����

������

�������

�����������������

������

����������

�������

���������������

�������

Rysunek 2.

Opis serwisu w formacie WSDL

background image

Software Developer’s Journal 3/2006

• spójne API – zapewniające łatwiejsze utrzymanie oraz

większy komfort pracy przy nim,

• niska cena – dzięki której szybciej zwrócą się koszty in-

westycji.

Niestety większość wymienionych narzędzi nie spełniania po-

wyższych wymogów. Małe i średnie firmy na ogół nie mogą po-

zwolić sobie na zakup komercyjnych rozwiązań takich jak bardzo

dobre np. WASP czy Weblogic Server. W wielu wypadkach rów-

nież wydajność tych rozwiązań pozostawia wiele do życzenia,

głownie ze względu na przetwarzanie komunikatów SOAP z wy-

korzystaniem modelu DOM, opierającego się na tworzeniu do-

kumentu będącego reprezentacją przetwarzanego XMLa, z któ-

rego dopiero w następnej kolejności tworzony jest odpowiadają-

cy danym XML obiekt logiki aplikacji. Podejście takie powoduje

poza spadkiem wydajności, również intensywne zużywanie pa-

mięci, gdyż każdy obiekt przechowywany jest w pamięci dwu-

krotnie, a drzewo przechowujące elementy dokumentu czasami

zajmuje kilkakrotnie więcej pamięci niż same dane . Z tym pro-

blemem boryka się między innymi Axis 1.x ( chociaż Axis 2 opie-

rać się będzie już na znacznie wydajniejszym modelu przetwa-

rzania XMLa Stax, umożliwiającym przetwarzanie danych stru-

mieniowo, na zasadzie iteratora) oraz JAX-RPC. Niewiele na-

rzędzi przejmuje się również łatwością użycia, wymagając czę-

Listing 1.

Struktura katalogów aplikacji

xfire
-

WEB-INF/

-

classes/

– klasy serwisu

-

META-INF/

-

xfire/

-

services.xml

– definicja serwisu

.-

lib/

– biblioteki wymagane przez kod

serwisu

web.xml

Listing 2.

Plik web.xml

<

?xml version=

"1.0"

encoding=

"ISO-8859-1"

?

>

<

!DOCTYPE web-app

PUBLIC

"-//Sun Microsystems,

Inc.//DTD Web Application 2.2//EN"

"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"

>

<

web-app

>

<!--Definicja servletu obsługjącego żądania SOAP -->

<

servlet

>

<

servlet-name

>

XFireServlet

<

/servlet-name

>

<

display-name

>

XFire Servlet

<

/display-name

>

<

servlet-class

>

org.codehaus.xfire.transport.http.XFire

ConfigurableServlet

<

/servlet-class

>

<

/servlet

>

<!-- Mapowanie servletu XFire na wszystkie adresy
rozpoczynające się od /services/* -->

<

servlet-mapping

>

<

servlet-name

>

XFireServlet

<

/servlet-name

>

<

url-pattern

>

/services/*

<

/url-pattern

>

<

/servlet-mapping

>

<

/web-app

>

background image

50

Inżynieria

oprogramowania

www.sdjournal.org

Software Developer’s Journal 3/2006

sto skomplikowanej konfiguracji, dodatkowych kroków w trakcie

instalacji lub udostępniając niewygodne API, wydłużając przez

to znacznie czas potrzebny na zrozumienie narzędzia oraz stwo-

rzenie aplikacji.

Dlaczego XFire?

XFire powstał jako odpowiedź na serie problemów, które napo-

tkał autor projektu podczas prób stworzenia webserwisu przy

użyciu dostępnych (m.in. wymienionych wcześniej) narzędzi. Ce-

lem było stworzenie darmowego narzędzia wolnego od wspo-

mnianych wad oraz zapewniającego wydajność komercyjnych

rozwiązań, posiadającego następujące cechy:

• niska cena - XFire jest narzędziem całkowicie darmowym

rozpowszechnianym wraz z kodem źródłowym,

• wysoka wydajność - jednym z podstawowych założeń pro-

jektu była wysoka wydajność rozwiązania, dlatego też archi-

tektura została całkowicie oparta na przetwarzaniu XMLa

przy użyciu bardzo wydajnego modelu StAX, umożliwiają-

cego inkrementalne przetwarzanie komunikatów oraz powo-

dującego minimalne wykorzystanie pamięci. Dodatkowo do

projektu wprowadzony został własny mechanizm mapowa-

nia komunikatów XML na obiekty Javy (zwany Aegis), będą-

cy jednym z najwydajniejszych rozwiązań tego typu obec-

nie dostępnych. Najlepszym zobrazowaniem korzyści pły-

nących z powyższych rozwiązań, są wyniki testów wydajno-

ściowych, które pokazują iż w zależności od rozmiaru komu-

nikatu SOAP silnik XFire jest od 2 do 5 razy szybszy od naj-

popularniejszego obecnie na rynku Axisa 1.x,

• spójne API – XFire posiada bardzo przejrzystą i intuicyj-

na, komponentową architekturę (http://xfire.codehaus.org/

Architecture), dzięki czemu w ciągu bardzo krótkiego czasu

możliwe jest zrozumienie zasad jego funkcjonowania.

• łatwość użycia - jednym z najważniejszych czynników

decydujących o sukcesie produktu jest czas potrzebny do

stworzenia danej aplikacji, dlatego też jednym z najważ-

niejszych celów projektu była jak największa łatwość je-

go użycia. Zostało to osiągnięte poprzez wprowadzenie

prostej i spójnej architektury oraz maksymalne uproszcze-

nie instalacji oraz konfiguracji (umożliwiającej jednak jed-

nocześnie wprowadzanie złożonych rozwiązań), o czym

przekonać się na poniższym przykładzie.

Webserwis w 5 min

Tworzenie strony serwerowej: Do stworzenia webserwisu po-

trzebujemy: dowolnego serwera aplikacji (np. Tomcat 5.x: http://
tomcat.apache.org
), dystrybucji XFire ( np. xfire-all-1.0-M6.zip lub

nowsza, która można pobrać ze strony: http://xfire.codehaus.org/
Download
) oraz dowolnego IDE Javy (np. Eclipse: http://
www.eclipse.org
). Aby zbudować nasz webserwis, należy utwo-

rzyć odpowiednią strukturę katalogów aplikacji, tak jak przedsta-

wia to Listing 1. Następnie musimy skopiować do katalogu biblio-

tek naszej aplikacji (WEB-INF/lib) następujące pliki: xfire-all-1.0-
SNAPSHOT.jar, stax-api-1.0.jar, wsdl4j-1.4.jar, xerces-2.4.0.jar,
xml-apis.jar, jdom-1.0.jar ,annogen-0.1.0.jar, qdox-1.5.jar, xbean-
spring-2.0-SNAPSHOT.jar,spring-1.2.4.jar, stax-1.1.2-dev.jar

Początkowa konfiguracja biblioteki XFire nie różni się zasad-

niczo od innych narzędzi tego typu, należy zdefiniować punkt do-

Listing 3.

Interfejs klasy implementującej funkcjonalność

aplikacji

package pl.sdj.petstore;

public

interface

PetStore

{

// kup zwierzę o zadanej nazwie

long

buyPet

(

String

name

)

;

//sprawdź status zamówienia

String

getOrderStatus

(

long

orderId

)

;

}

Listing 4.

Implementacja funkcjonalności aplikacji

package pl.sdj.petstore.impl;
import pl.sdj.petstore.PetStore;

public

class

PetStoreImpl

implements

PetStore

{

public

String

getOrderStatus

(

long

orderId

)

{

// mamy tylko "mysz" w magazynie

if

(

orderId

==

"mysz"

.

hashCode

())

{

return

"zamowiony"

;

}

return

"nieznany"

;

}

public

long

buyPet

(

String

name

)

{

// zwroc hashcode jako identyfikator zlecenia

return

(

name

==

null

?

-

1

:

name

.

hashCode

())

;

}

Przydatne linki

zbiór specyfikacji

http://www.w3.org/2002/ws/

strona domowa XFire

http://xfire.codehaus.org

serwis poświęconych webserwisom

http://webservices.xml.com/

zbiór artykuł dotyczących webserwisów

http://webservices.oreilly.com/

serwis poświęconych webserwisom

http://webservices.org/

strona domowa organizacji zajmującej się rozwojem standar-

dów webserwisów

http://www.oasis-open.org

• organizacja promująca przenośność implementacji webserwisów

http://www.ws-i.org/

• strona domowa pakietu Axis

http://ws.apache.org/axis

Webserwis

Zbiór samo-opisujących się (przy pomocy języka WSDL) obiektów,
dostarczających dane oraz usługi w niezależny od platformy spo-
sób ( dzięki użyciu opartemu na formacie XML protokołowi SOAP),
udostępnionych z użyciem ustandaryzowanych protokołów komuni-
kacji (jak HTTP, JMS).

background image

51

Webserwisy: XFire w akcji

www.sdjournal.org

Software Developer’s Journal 3/2006

Listing 6.

Struktura pliku konfiguracyjnego

stępu (w postaci servletu), który będzie odpowiedzialny za prze-

chwytywania żądań klientów i przekazywanie ich do właściwych

klas. W tym celu musimy stworzyć plik web.xml naszej aplikacji

o zawartości przedstawionej na Listingu 2.

Od tego mementu wszystkie żądania odnoszące się do

adresów rozpoczynających się w przypadku serwera Tom-

cat (przy założeniu iż serwer pracuje na domyślnym porcie,

a nasza aplikacji skonfigurowana pod nazwą XFire) od http://
localhost:8080/xfire/services
, będą traktowane jako żądania

webserwisu i przekazywane do serwletu XFire.

Następnie musimy utworzyć klasy implementujące funk-

cjonalność naszej aplikacji, w postaci interfejsu (Listing 3)

oraz jego implementacji (Listing 4).

Kolejnym krokiem procesu konfiguracji jest wskazanie,

które klasy naszej aplikacji powinny być udostępnione jako

webserwisy. W tym celu należy utworzyć plik services.xml

w katalogu META-INF/xfire o zawartości przedstawionej na Li-

stingu 5, w którym poszczególne znaczniki mają następujące

znaczenie:

name

– jest nazwą pod jaką serwis będzie dostępny (np.

http://localhost:8080/xfire/services/PetStore ),

namespace

– przestrzeń nazw serwisu,

serviceClass

– klasa interfejsu definiująca metody serwisu,

implementationClass

– klasa implementująca serwis,

Po zbudowaniu naszej aplikacji i zainstalowaniu na serwe-

rze, mamy już w pełni działający webserwis. Aby upew-

nić się że wszystko działa poprawnie w oknie przeglądar-

ki wpisujemy następujący adres http://localhost:8080/xfire/

Listing 5.

Konfiguracja serwisu - plik META-INF/xfire/

services.xml

<

beans xmlns=

"http://xfire.codehaus.org/config/1.0"

>

<

service

>

<

name

>

PetStore

<

/name

>

<

namespace

>

http://www.sdj.pl

<

/namespace

>

<

serviceClass

>

pl.sdj.petstore.PetStore

<

/serviceClass

>

<

implementationClass

>

pl.sdj.petstore.impl.PetStoreImpl

<

/implementationClass

>

<

/service

>

<

/beans

>

<

beans xmlns=

"http://xfire.codehaus.org/config/1.0"

>

<!-- Definicja globalnych (uruchamianych dla wszystkich
zdefiniowanych serwisów) klas przetwarzających
komunikaty przychodzące,

zwracane oraz powiadomienia

o błędach. -->

<

xfire

>

..

<

inHandlers

><

handler handlerClass=

""

/

>

<

/inHandlers

>

<

outHandlers

><

handler handlerClass=

""

/

>

<

/outHandlers

>

<

faultHandlers

><

handler handlerClass=

""

/

>

<

/faultHandlers

>

<

/xfire

>

<!-- Definicja serwisu -->

<

service

>

<!-- Nazwa serwisu -->

<

name

/

>

<!-- Interfejs definiujący które metody będą udostępnione
jako webserwisy -->

<

serviceClass

/

>

<!-- Klasa implementująca serwis -->

<

implementationClass/

>

<!-- Przestrzeń nazw używana w komunikatach SOAP -->

<

namespace

/

>

<!-- Klasa fabryki odpowiedzialna za utworzenie obiektu
serwisu.

Można wskazać własną klasę fabryki, która

wykona dodatkowe czynności w trakcie tworzenie obiektu
lub wskazać iż chcemy zdefiniować nasz serwis za
pomocą annotacji podając jedną z predefiniowanych
fabryk: commons-attributes lub jsr181 (http://
xfire.codehaus.org/JSR+181+Service) -->

<

serviceFactory/

>

<!-- Definiuje sposób budowania komunikatów SOAP: „wrapped”
lub „document” -->

<

style/

>

<!-- Wersja specyfikacji SOAP: 1.1 (domyślnie) lub 1.2 -->

<

soapVersion

/

>

<!-- Zmienne ustawiane na obiekcie serwisu. Dzięki nim
możliwe jest np. zabronienie generowania opisu WSDL po
wpisaniu w przeglądarce

adresu serwisu zakończonego

„?wsdl”. -->

<

properties

>

<

property key=

"key"

>

value

<

/property

>

<

/properties

>

<!-- Definicja klas przetwarzających komunikaty
przychodzące,

zwracane i powiadomienia o błędach. -->

<

inHandlers

><

handler handlerClass=

""

/

>

<

/inHandlers

>

<

outHandlers

><

handler handlerClass=

""

/

>

<

/outHandlers

>

<

failtHandlers

>

<

handler handlerClass=

""

/

>

<

/faultHandlers

>

Słownik terminów

• SOAP (Simple Object Access Protocol) – oparty na formacie

XML protokół umożliwiający wywoływanie zdalnych metod,

• WSDL (Web Services Description Language) - język opisu

właściwości webserwisu,

• UDDI (Universal Description, Discovery and Integration) – de-

finiuje sposób rejestrowania oraz odnajdywania webserwisów,

• StAX (Streaming API for XML) – metoda przetwarzania da-

nych XML polegająca na inkrementalnym pobieraniu ich z
parsera (ang. Pull-parsing),

• DOM (Document Object Model) – metoda przetwarzania da-

nych XML polegająca na obrabianiu drzewa węzłów zbudo-
wanego na podstawie tych danych.

background image

52

Inżynieria

oprogramowania

www.sdjournal.org

Software Developer’s Journal 3/2006

services/PetStore?wsdl, pod którym powinniśmy zobaczyć

XMLowy opis naszego serwisu w formacie WSDL.

Powyższy przykład pokazuje możliwość stworzenia

w pełni działającego serwisu, przy użyciu dosłownie kilku li-

nii konfiguracji, jednak pomimo prostoty, konfiguracja XFi-

re umożliwia wpływanie praktycznie na każdy aspekt dzia-

łania aplikacji. Podstawowy format konfiguracji umożliwia

zdefiniowanie następujących elementów, przedstawionych

na Listingu 6.

Teraz, kiedy wiemy, że serwis działa oraz znamy trochę

więcej możliwości konfiguracyjnych, możemy wzbogacić je-

go funkcjonalność np. o funkcje ograniczającą zdolność wy-

woływania jego metod tylko do klientów łączących się z za-

danego adresu IP. Taką funkcjonalność otrzymać można

wykorzystując tzw. „handlery”, czyli klasy, których kod bę-

dzie wykonywany przy każdym wywołaniu metod serwisu.

Obiekty handlerów możemy zarejestrować dla wszystkich

komunikatów przychodzących (

inHandlers

– wywołań me-

tod), wychodzących (

outHandlers

– rezultatów wywołania

metod) oraz powiadomień o błędach (

faultHandlers

– prze-

kazujących informacje o błędzie który wystąpił w trakcie wy-

wołania metody). Klasy te możemy rejestrować zarówno dla

pojedynczego serwisu jak i globalnie, dla wszystkich zdefi-

niowanych serwisów. Dodatkowo mogą one być umieszcza-

ne na różnych etapach (zwanych fazami, zdefiniowanymi

w klasie

Phase

) przetwarzania komunikatu, a więc nasza lo-

gika może zostać „wpięta” w moment parsowania komunika-

tu (

PARSE

), wybierania serwisu do którego ma zostać prze-

kazany komunikat (

DISPATCH

) , tuż przed wywołaniem meto-

dy serwisu (

PRE-INVOKE

) lub też w dowolnym innym punkcie,

który potrzebujmy wykorzystać. Dzięki takiej elastyczności

bez większych problemów możemy do naszej aplikacji do-

dać funkcjonalność szyfrowania lub cyfrowego podpisywa-

nia komunikatów SOAP, autentykacji użytkownika lub wer-

sjonowania API naszego serwisu.

Klasa naszego handlera może wyglądać tak jak zostało to

przedstawione na Listingu 7.

Najważniejszą częścią kodu jest metoda „invoke”, która

wykonywana jest przy przetwarzaniu każdego komunikatu.

W metodzie tej z żądania HTTP (HTTPServletRequest) po-

bierany jest adres IP klienta wywołującego metodę serwisu, a

następnie porównywany z adresem IP dozwolonym dla dane-

go serwisu, zdefiniowanym w pliku konfiguracyjnym. Metoda

getPhase

decyduje, w którym miejscu łańcucha przetwarzania

komunikatu zostanie umieszczona nasza klasa (Przetwarza-

nie komunikatów przychodzących składa się z następujących

faz:

TRANSPORT

,

PARSE, PRE _ DISPATCH

,

DISPATCH

,

POLICY

,

USER

,

PRE _ INVOKE, SERVICE

).

Aby móc testować powyższy kod wewnątrz naszego

IDE, do bibliotek aplikacji musimy dodać plik servletapi-
2.3.jar
z dystrybucji XFire. Następnie nasza klasa musi zo-

stać zarejestrowana w serwisie jako

handler

, poprzez doda-

nie poniższego wpisu do pliku

services.xml

(Listing 8). Po

zbudowaniu aplikacji, możemy być pewni, iż nikt niepożą-

dany nie będzie miał dostępu do naszej, z „takim trudem”

stworzonej funkcjonalności.

Tworzenie klienta

Przykładowym klientem naszego serwisu będzie prosta aplika-

cja konsolowa. Do jej uruchomienia potrzebujemy następujących

bibliotek, dostarczonych z dystrybucją pakietu: commons-disco-
very-0.2.jar
, commons-logging-1.0.4.jar, log4j-1.2.8.jar, wsdl4j-
1.5.1.jar
, jdom-1.0.jar, servletapi-2.3.jar, stax-1.1.2-dev.jar,stax-api-
1.0.jar, xerces-2.4.0.jar, xfire-all-1.0-SNAPSHOT.jar, xml-apis.jar,

Listing 7.

Implementacja klasy handlera

package pl.sdj.handlers;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.handler.AbstractHandler;
import org.codehaus.xfire.transport.http.
XfireServletController;

public

class

IPRestrictionHandler

extends

AbstractHandler

{

public

void

invoke

(

MessageContext

ctx

)

throws

Exception

{

// pobierz adres zdalnego klienta

String

remoteIp

=

XfireServletController

.

getRequest

()

.

getRemoteAddr

()

;

// pobierz dozwolny adres klienta

String

allowedIP

=

(

String

)

ctx

.

getService

()

.

getProperty

(

"allowedIP"

)

;

System

.

out

.

println

(

"Proba wywolania metody:"

+

ctx

.

getInMessage

()

.

getAction

()

+

" z adresu "

+

remoteIp

)

;

// porownaj adresy

if

(

!

remoteIp

.

equals

(

allowedIP

)){

// jezeli adresy nie sa rowne przerwij przetwarzanie

// komunikatu

throw

new

XFireException

(

"Twój adres IP nie należy

do dozwolonych"

)

;

}

}

// okresla w którym miejscu łańcucha wywołań należy
// umieścić nasz handler

public

String

getPhase

() {

return

Phase

.

USER

;

}

}

Listing 8.

Rozszerzona konfiguracja serwisu

<

beans xmlns=

"http://xfire.codehaus.org/config/1.0"

>

<

service

>

<

name

>

PetStore

<

/name

>

<

namespace

>

http://www.sdj.pl

<

/namespace

>

<

serviceClass

>

pl.sdj.petstore.PetStore

<

/serviceClass

>

<

implementationClass

>

pl.sdj.petstore.impl.PetStoreImpl

<

/implementationClass

>

<

properties

>

<

property key=

"allowedIP"

>

127.0.0.1

<

/property

>

<

/properties

>

<

inHandlers

>

<

handler handlerClass=

"

pl.sdj.handlers.IPRestrictionHandler"

/

>

<

/inHandlers

>

<

/service

>

<

/beans

>

background image

53

Webserwisy: XFire w akcji

www.sdjournal.org

Software Developer’s Journal 3/2006

Listing 9.

Implementacja klienta serwisu

public

class

XfireClient

{

private

static

final

String

NAME

=

"PetStore"

;

private

static

final

String

NAMESPACE

=

"http://www.sdj.pl"

;

private

static

final

Class

SERVICECLASS

=

PetStore

.

class

;

private

static

final

String

SERVICE_ADDRESS

=

"http://127.0.0.1:8080/xfire/services/PetStore"

;

private

PetStore

service

;

public

void

init

()

{

Service

serviceModel

=

new

ObjectServiceFactory

()

.

create

(

SERVICECLASS

,

NAME

,

NAMESPACE

,

null

)

;

try

{

service

=

(

PetStore

)

new

XfireProxyFactory

()

.

create

(

serviceModel

,

SERVICE_ADDRESS

)

;

}

catch (MalformedURLException e)

{

throw

new

RuntimeException

(

"Niepoprawny adres

serwisu:"

+

e

.

getMessage

())

;

}

}

public

void

buyPet

()

throws

Exception

{

System

.

out

.

println

(

"Kupuje 'mysz'"

)

;

long

orderId

=

service

.

buyPet

(

"mysz"

)

;

System

.

out

.

println

(

"Identyfikator zakupu to:"

+

orderId

)

;

String

status

=

service

.

getOrderStatus

(

orderId

)

;

System

.

out

.

println

(

"Status zlecenia zakupu:"

+

status

)

;

}

public

static

void

main

(

String

[]

args

)

throws

Exception

{

XFireClient

client

=

new

XFireClient

()

;

client

.

init

()

;

client

.

buyPet

()

;

}

}

W następnej kolejności tworzony jest obiekt pośrednika

(

XFireProxy

), odpowiedzialnego za delegowanie wywołań me-

tod do zdalnego serwisu. Jako parametry, należy podać zde-

finiowany wcześniej serwis oraz adres serwisu, z którego me-

tody chcemy wywołać. Od tego momentu możemy pracować

ze zdalnym serwisem dokładnie tak samo jak używamy lokal-

nych obiektów.

Po uruchomieniu kodu klienta, na konsoli powinniśmy

otrzymać wynik podobny do przedstawionego w Listingu 10.

Co dalej?

Oczywiście możliwości, które oferuje biblioteka XFire są dużo

większe niż opisany powyżej przykład, zarówno pod wzglę-

dem łatwości użycia jak i oferowanej funkcjonalności. Najcie-

kawsze cechy biblioteki XFire:

• XFire niezwykle łatwo integruje się z popularnymi konte-

nerami jak Spring , PiccoContainer czy Loom, dzięki te-

mu za pomocą kilku linii kodu możliwe jest udostępnienie

serwisu lub stworzenie klienta (http://xfire.codehaus.org/
Container+Support
),

• serwis może zostać zdefiniowany za pomocą anotacji Ja-

va 1.5 lub ich odpowiednika

commons-attributes

(http://

xfire.codehaus.org/JSR+181+Annotations),

• zależnie od potrzeb czy wymagań biznesowych XFire

pozwala na zastosowanie rożnych bibliotek służących

do mapowania obiektów Javy na format XML (ang. Data

binding ) jak Aegis, XMLBeans, Jaxb 1.1 i 2.0,

• poza transportem opartym na protokole HTTP, możli-

we jest również wykorzystanie komunikacji z użyciem ko-

munikatów JMS oraz asynchronicznego protokołu XMPP/

Jabber,

• XFire może zostać również osadzony wewnątrz dowol-

nej aplikacji, która dzięki temu może funkcjonować ja-

ko silnik SOAP, dostarczając np. swojej własnej metody

konfiguracji.

Cały czas trwają również prace nad dodawaniem nowych

możliwości oraz lepszym wsparciem dla opracowanych

standardów, między innymi takich jak WS-Security (odpo-

wiedzialnych za szyfrowanie, podpis cyfrowy wymienianych

wiadomości) czy WS-Policy (umożliwiających uzgodnienie

wymagań oraz możliwości obu stron komunikacji).

Jeżeli jednak zdarzy się sytuacja, że biblioteka XFire

nie posiada funkcjonalności, której potrzebujecie, nic nie

stoi na przeszkodzie, aby poprosić o jej dodanie. Na pew-

no znajdzie się ktoś, kto wysłucha prośby, a w większości

przypadków zaimplementuje to tak szybko jak tylko to moż-

liwe. Z zespołem XFire skontaktować się można poprzez

grupy dyskusyjne, kanał IRC (http://xfire.codehaus.org/
Support
) lub dodając wpis z propozycją zmiany do systemu

zgłaszania błędów JIRA (http://jira.codehaus.org/secure/Br
owseProject.jspa?id=10750
). n

Listing 10.

Wynik wywołania klienta

Kupuje 'mysz'
Identyfikator zakupu to :3367187
Status zlecenia zakupu :zamowiony

javamail-1.3.2.jar, commons-httpclient-3.0-rc3.jar, commons-co-
dec-1.3.jar
oraz klasa interfejsu naszego serwisu

PetStore

, przed-

stawiona na Listingu 9.

Najbardziej interesującą częścią powyższego kodu

jest metoda

init

, w której utworzony zostaje obiekt serwi-

su, przy pomocy którego, będziemy się odwoływać do je-

go zdalnej instancji. Musi on zostać zainicjowany dokład-

nie takimi samymi wartościami jak jego odpowiednik po

stronie serwera, a więc za parametry należy podać odpo-

wiedniki następujących wpisów z pliku konfiguracyjnego

servies.xml

:

ObjectServiceFactory().create(<serviceClass>,<name>,<namespace>,
properties);

gdzie parametr properties umożliwia przekazanie dodatków

parametrów jak wersja protokołu SOAP czy sposobu genero-

wania komunikatów.


Wyszukiwarka

Podobne podstrony:

więcej podobnych podstron