<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>j2ee.pl - związani z javą &#187; adb</title>
	<atom:link href="http://j2ee.pl/tag/adb/feed/" rel="self" type="application/rss+xml" />
	<link>http://j2ee.pl</link>
	<description>związani z Javą</description>
	<lastBuildDate>Mon, 24 Aug 2009 11:45:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Tworzenie WebService&#8217;ów z wykorzystaniem Axis2</title>
		<link>http://j2ee.pl/2007/08/25/tworzenie-webserviceow-z-wykorzystaniem-axis2/</link>
		<comments>http://j2ee.pl/2007/08/25/tworzenie-webserviceow-z-wykorzystaniem-axis2/#comments</comments>
		<pubDate>Sat, 25 Aug 2007 11:54:13 +0000</pubDate>
		<dc:creator>Michał Mally</dc:creator>
				<category><![CDATA[WebServices]]></category>
		<category><![CDATA[adb]]></category>
		<category><![CDATA[axis2]]></category>
		<category><![CDATA[web service]]></category>
		<category><![CDATA[wsdl]]></category>

		<guid isPermaLink="false">http://j2ee.pl/2007/08/25/tworzenie-webserviceow-z-wykorzystaniem-axis2/</guid>
		<description><![CDATA[
Wprowadzenie
Poniższy artykuł zredagowany został z myślą o przedstawieniu podstawowych zagadnień związanych z tworzeniem usług typu WebService. Przy czym przez tworzenie WebService&#8216;u należy tutaj rozumieć zarówno przygotowanie serwerowej, jak i klienckiej warstwy rozwiązania. W osiągnięciu tego celu pomoże nam Axis2 &#8211; darmowe silnik WebService&#8216;ów.  Wybór tego akurat produktu o tyle nie jest przypadkowy, że zaledwie [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://ws.apache.org/axis2/images/axis.jpg" alt="Axis2" /></p>
<h3>Wprowadzenie</h3>
<p>Poniższy artykuł zredagowany został z myślą o przedstawieniu podstawowych zagadnień związanych z tworzeniem usług typu <strong>WebService</strong>. Przy czym przez tworzenie <strong>WebService</strong>&#8216;u należy tutaj rozumieć zarówno przygotowanie serwerowej, jak i klienckiej warstwy rozwiązania. W osiągnięciu tego celu pomoże nam <strong>Axis2</strong> &#8211; darmowe silnik <strong>WebService</strong>&#8216;ów.  Wybór tego akurat produktu o tyle nie jest przypadkowy, że zaledwie kilka dni temu światło dzienne ujrzała wersja 1.3 tego popularnego produktu na &#8220;miłej&#8221; i lubianej licencji <strong>Apache</strong>&#8216;a.</p>
<p><span id="more-76"></span>W celu jak najlepszego zaprezentowania omawianego zagadnienia posłużymy się, przygotowaną specjalnie na tą potrzebę, prostą aplikacją. W kolejnych krokach postaramy się przejść przez wszystkie konieczne etapy do stworzenia kompletnej, w pełni działającej aplikacji. Należy jednak tutaj zauważyć, że technologia <strong>WebService</strong>&#8216;ów często wykorzystywana jest w intencji udostępnienia pewnej istniejącej już funkcjonalności instytucjom zewnętrznym, a co za tym idzie odpowiedzialność za implementację strony serwerowej spada na zupełnie inne osoby niż odpowiedzialność za implementację strony klienckiej. Co więcej, środowiska wykonywalne każdej z nich mogą drastycznie się różnić. Na tym jednak polega moc rozwiązań opartych na <strong>WebService</strong>&#8216;ach. Postaramy się więc prezentować powyższe 2 etapy jako możliwie od siebie niezależne, z tym jedynie małym zastrzeżeniem, że w momencie przystąpienia do implementacji klienta, produkcja serwera będzie już ukończona.</p>
<p>W artykule staraliśmy się przedstawić ogólny zarys <strong>WebService</strong>&#8216;ow &#8211; ma on charakter poglądowy i zawiera jedynie szczątkowe informacje na temat samego <strong>Axis2</strong> i jego możliwości w zakresie tworzenia ogólnych serwisów. Nie zawiera informacji na temat rozbudowanych możliwości w zakresie rozbudowy oraz konfiguracji szczególnych dla <strong>Axis2</strong>. W dokumencie brak również podstaw teoretycznych związanych z samymi <strong>WebService</strong>&#8216;ami. Mamy jednak nadzieję, że osoby zainteresowane tematyką sięgną po ogólniedostępne materiały dodatkowe. Część z nich staraliśmy się wymienić pod koniec artykułu.</p>
<p>Serdecznie zapraszam więc do zapoznania się z pozostałą częścią artykułu mając jednocześnie nadzieję, że będzie ona stanowiła dla Państwa interesującą lekturę. :)</p>
<h3>Kontekst rozwiązania</h3>
<p>Problem, z jakim będziemy się borykali, osadzimy (w jakże popularnych dla wielu z nas ;)) realiach pracowniczych. Naszym celem będzie udostępnienie poprzez <strong>WebService</strong>&#8216;y funkcjonalności dostępnej lokalnie w postaci klas POJO (<em>plain-old java objects</em>).</p>
<p>Funkcjonalność, o której mowa powyżej to usługa odpowiedzialna za uzupełnienie informacji na temat wybranych pracowników włącznie z danymi na temat ich bezpośrednich jak i pośrednich podwładnych. Ze względu na niedostępność dla nas prawdziwej usługi tego typu oraz ustawę o ochronie danych osobowych ;) przygotowałem prostą implementację, która będzie jedynie w bardzo &#8220;naiwny&#8221; sposób imitowała prawdziwe zachowanie tejże usługi.</p>
<p>Na całość będzie składać się zaledwie kilka prostych klas, których fragmenty dla ustalenia uwagi pozwoliłem sobie zaprezentować poniżej.</p>
<pre class="prettyprint">
package pl.jcommerce.example.pracownik;

import pl.jcommerce.example.Identyfikator;

public class Pracownik {
  private Identyfikator identyfikator;
  private String imie;
  private String nazwisko;
  private int rokUrodzenia;
  private Pracownik[] podwladni;

  //settery i gettery

}</pre>
<p>Klasa <strong>Pracownik</strong> będzie jedyną klasą domenową naszej usługi. Można zauważyć, że jest to bardzo prosta implementacja, a mimo to zawierająca już kilka interesujących elementów na które będzie warto zwrócić uwagę w kontekście tworzenia i wykorzystywania pliku definicji <strong>WebService</strong>&#8216;u (<em>WSDL</em>). Między innymi możliwe stanie się zaobserwowanie sposobu w jaki <strong>Axis</strong> poradzi sobie z generacją pliku <strong>WSDL</strong> w aspekcie zachowania związanego z prezentowaniem referencji do innego złożonego elementu, a także do tablicy obiektów.</p>
<pre class="prettyprint">
public interface PracownikUzupelnianieInformacji {
  public Pracownik[] uzupelnijInformacjeOPracownikach(Pracownik[] pracownicy,int glebokoscUzupelniania) throws ObjectNotFoundException, IdentyfikatorNotSetException;
}</pre>
<p>Powyższy interfejs będzie stanowił interfejs naszej usługi, którą będziemy chcieli udostępnić na zewnątrz. Aby udało się przetestować działanie implementowanego rozwiązania stworzyłem również prostą klasę <em>stub</em>&#8216;a, która w odpowiedzi na zgłoszone żądania w sposób mniej lub bardziej losowy uzupełnia dane na temat pracowników przekazanych w zapytaniu, a także na temat ich podwładnych. Ze względów wydajnościowych maksymalna ilość podwładnych jak i głębokość uzupełniania zostały ograniczone. Dodatkowo różne wywołania metody przy dostarczeniu tych samych parametrów operacji mogą zwrócić różne rezultaty. Z naszego jednak punktu widzenia wszystkie wymienione tutaj <em>ułomności</em> nie będą miały żadnego znaczenia.</p>
<h3>Prerekwizyty</h3>
<p>By rozpocząć musimy mieć zainstalowane i poprawnie skonfigurowane zintegrowane środowisko developerskie. Przykłady zawarte w artykule zostaną przygotowane z wykorzystaniem <a href="http://eclipse.org/">Eclipse</a>&#8216;a.</p>
<p>W dalszej części będziemy także korzystać z kontenera serwletów. W przykładzie wykorzystamy <a href="http://tomcat.apache.org/">Apache Tomcat&#8217;a</a> v6.0.x lecz nie powinno także być problemów z uruchomieniem rozwiązania na innych implementacjach. Warto także nadmienić, że silnik <strong>Axis2</strong> udostępniany jest także w wersji nie wymagającej stosowania dodatkowych aplikacji, czy też bibliotek (<em>standalone application</em>).</p>
<p>Przed przystąpieniem do kolejnych kroków warto pobrać kompletne <a href='http://j2ee.pl/wp-content/uploads/2007/08/pljcommerceexamplepracownik.zip'>spakowane źródła</a> przygotowywanego rozwiązania (2 projekty utworzone z wykorzystaniem <strong>Eclipse</strong>&#8216;a). Po rozpakowaniu archiwum należy pamiętać, aby zastąpić puste pliki <em>.jar</em> kopiami znajdującymi w dystrybucji <strong>Axis2</strong>.</p>
<h3>Instalacja Axis2</h3>
<p>W naszym przypadku najbardziej odpowiednim wyjściem będzie pobranie <a href="http://ftp.tpnet.pl/vol/d1/apache/ws/axis2/1_3/axis2-1.3-bin.zip">standardowej dystrybucji</a> <strong>Axis</strong>&#8216;a. Zdecydujemy się na pobranie tej wersji ze względu na dostępność w niej dodatkowych narzędzi linii poleceń, które wykorzystamy do przygotowania klienta.</p>
<p>Jak już wcześniej wspomniałem <strong>Axis2</strong> dysponuje aplikacją uruchamialną w kontenerze servlet&#8217;ów. W celu przeprowadzenia jej instalacji należy plik <em>Axis2.war</em> znajdujący się w pobranej przez nas dystrybucji wdrożyć w kontenerze serwletów. W przypadku <strong>Apache Tomcat</strong>&#8216;a wystarczy plik ten skopiować do katalogu <em>webapps</em>, a następnie uruchomić serwer. Już w tym momencie powinniśmy uzyskać w pełni działający engine <strong>Axis</strong>&#8216;a. Weryfikacji tego faktu można dokonać w prosty sposób poprzez wpisanie w przeglądarce internetowej odpowiedniego adresu. Przy standardowej konfiguracji <strong>Apache Tomacat</strong>&#8216;a powinien to być następujący URL: <a href="http://localhost:8080/axis2">http://localhost:8080/axis2</a>.</p>
<p>Naszym oczom ukaże się strona główna <strong>Axis</strong>&#8216;a, gdzie powinniśmy mieć możliwość zweryfikowania poprawności instalacji modułu poprzez wybranie opcji <em>Validate</em>. Interfejs <strong>Axis</strong>&#8216;a udostępniany poprzez przeglądarkę daje nam także możliwość weryfikacji uruchomionych serwisów oraz administracji samym silnikiem.</p>
<p>Jeżeli wszystko, jak do tej pory poszło, zgodnie z planem możemy zabrać się za przygotowanie serwisu, który następnie zostanie uruchomiony w środowisku <strong>Axis</strong>&#8216;a. W przypadku wystąpienia problemów na tym lub późniejszym etapie odsyłam do strony głównej Axis2, gdzie można znaleźć bardzo wiele wartościowych informacji.</p>
<h3>Przygotowanie warstwy serwera</h3>
<p>Aby rozpocząć pracę nad serwisem będziemy potrzebowali <a href="http://j2ee.pl/wp-content/uploads/2007/08/pracownikuzupelnianieinformacjiserversrc.zip">kodu źródłowego usługi</a>, którą powyżej ogólnie już zaprezentowaliśmy.</p>
<p>Jedną z zalet <strong>Axis2</strong> jest jego duża elastyczność oraz rozszerzalność o nowe moduły funkcjonalne. Także w kwestii przygotowania serwera <strong>WebService</strong>&#8216;u dysponuje on wieloma znacznie różniącymi się między sobą rozwiązaniami. My zdecydowaliśmy się na jedną z nich, a mianowicie na wykorzystanie obiektów <em>POJO</em> &#8211; to podejście (jak każde) ma swoje liczne zalety i wady. Dla nas czynnikiem decydującym był aspekt czasowy przygotowania <strong>WebService</strong>&#8216;u. Zainteresowanym informacjami na temat szczegółowych różnic w samej implementacji jak i funkcjonowaniu rozwiązań przygotowanych przy stosowaniu dostępnych podejść odsyłamy do oficjalnej dokumentacji.</p>
<p>Obrane przez nas podejście będzie wymagało przygotowania pliku o rozszerzeniu <em>aar</em>. W rzeczywistości plik ten będzie zwykłym archiwum <em>ZIP</em> posiadającym podobną strukturę plików i katalogów jak dobrze znane pliki <em>JAR</em>. Z tego też względu możliwe stanie się wykorzystanie istniejącego już zadania <strong>Apache Ant</strong>&#8216;a. W pliku <em>AAR</em> powinny się znajdować następujące elementy:</p>
<ul>
<li>META-INF/services.xml &#8211; definicja serwisu wymagana przez <strong>Axis</strong>&#8216;a</li>
<li>lib &#8211; katalog z bibliotekami (<em>*.jar</em>) wykorzystywanymi przez serwis</li>
<li><em>skompilowane pliki źródeł</em></li>
</ul>
<p>W naszym przypadku katalog <em>lib</em> nie wystąpi ze względu na fakt, że przygotowana usługa nie korzysta z innej funkcjonalności niż tej dostarczanej przez klasy <em>JSE</em>. Jednakże w większości przypadków, z wyłączeniem tak trywialnych przykładów jak ten, korzystanie z bibliotek zewnętrznych będzie niemal koniecznością.</p>
<p>Skupmy naszą uwagę na nowym elemencie, jaki pojawia się w archiwum <em>AAR</em>, a mianowicie na pliku <em>services.xml</em>.</p>
<pre class="prettyprint">
&lt;service name="PracownikUzupelnianieInformacji" scope="application"&gt;
  &lt;description&gt;Serwis uzupelnianiajacy informacje o pracowniku&lt;/description&gt;
  &lt;messageReceivers&gt;
    &lt;messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /&gt;
  &lt;/messageReceivers&gt;
  &lt;parameter name="ServiceClass"&gt;pl.jcommerce.example.pracownik.service.PracownikUzupelnianieInformacjiImpl&lt;/parameter&gt;
&lt;/service&gt;</pre>
<p>Jak widać definicja serwisu w naszym przypadku zawiera jedynie kilka elementów, które wydają się być łatwe do zrozumienia. Szczególną uwagę należy zwrócić na tag <em>&lt;parameter&gt;</em> o atrybucie <em>name</em> równym <em>ServiceClass</em>. Definiuje on klasę, której instancja posłuży jako końcówka <strong>WebService</strong>&#8216;u po stronie serwera. W wielu przypadkach implementacji serwisów w oparciu o podejście <em>POJO</em> będzie to jeden z niewielu elementów, jakich zmiany będzie się od nas wymagało. Tag <em>messageReceivers</em> definiuje klasy odpowiedzialne za obsługę przesyłania informacji pomiędzy klientem, serwerem usługi <strong>WebService</strong>&#8216;u. Zaprezentowany tutaj przykład jest bardzo prosty, lecz w ogólności plik definicji serwisu udostępnia rozwinięte możliwości modyfikacji zachowania serwisu.</p>
<p>Bardzo interesującą kwestią jest brak jakiegokolwiek pliku <em>WSDL</em>, ale jego brak jak się później okaże jest jedynie pozorny.</p>
<p>W wypadku konieczności wstępnej konfiguracji obiektu usługi można wykorzystać framework <strong>Spring</strong> z którym <strong>Axis2</strong> potrafi bardzo dobrze się zintegrować. Artykuł ten nie pokrywa jednak w zupełności tej tematyki.</p>
<p>W tym momencie posiadając już kompletną listę plików wchodzących w skład archiwum <em>AAR</em> możemy przystąpić do stworzenia samego archiwum. Można tego dokonać oczywiście ręcznie &#8211; ja natomiast posłużyłem się do tego bardzo prostym plikiem <em>build.xml</em> programu <strong>Apache Ant</strong>:</p>
<pre class="prettyprint">
&lt;project name="PracownikUzupelnianieInformacji" default="dist" basedir="."&gt;
  &lt;property name="location.dir.src" location="src" /&gt;
  &lt;property name="location.dir.bin" location="bin" /&gt;
  &lt;property name="location.dir.build" location="build" /&gt;
  &lt;property name="location.dir.dist" location="dist" /&gt;
  &lt;property name="location.dir.resources" location="resources" /&gt;
  &lt;property name="location.dir.resources.aar" location="${location.dir.resources}/aar" /&gt;
  &lt;property name="file.aar" value="PracownikUzupelnianieInformacji.aar"/&gt;
  &lt;target name="clean"&gt;
    &lt;mkdir dir="${location.dir.bin}" /&gt;
    &lt;mkdir dir="${location.dir.build}" /&gt;
    &lt;delete dir="${location.dir.build}" excludes="${location.dir.build}"/&gt;
    &lt;mkdir dir="${location.dir.dist}" /&gt;
    &lt;delete dir="${location.dir.dist}" excludes="${location.dir.dist}"/&gt;
  &lt;/target&gt;
  &lt;target name="compile" depends="clean"&gt;
    &lt;javac srcdir="${location.dir.src}" destdir="${location.dir.bin}" /&gt;
  &lt;/target&gt;
  &lt;target name="build" depends="compile"&gt;
    &lt;copy todir="${location.dir.build}"&gt;
      &lt;fileset dir="${location.dir.resources.aar}" /&gt;
      &lt;fileset dir="${location.dir.bin}" /&gt;
    &lt;/copy&gt;
  &lt;/target&gt;
  &lt;target name="dist" depends="build"&gt;
    &lt;jar destfile="${location.dir.dist}/${file.aar}" basedir="${location.dir.build}"/&gt;
  &lt;/target&gt;
&lt;/project&gt;</pre>
<p>Wywołanie domyślnego zadania zdefiniowanego w tym pliku budowania powinno skutkować utworzeniem w katalogu <em>dist</em> gotowego pliku z rozszerzeniem <em>aar</em> gotowego do wdrożenia w środowisku <strong>Axis</strong>&#8216;a.</p>
<h3>Wdrażanie serwisu w środowisku uruchomieniowym Axis2</h3>
<p>Do wdrożenia przygotowanego w poprzednim podrozdziale serwisu wykorzystamy jedną z udostępnianych przez <strong>Axis</strong>&#8216;a w tym celu metod. Należy się upewnić, że uprzednio zainstalowany silnik <strong>WebService</strong>&#8216;ów wciąż działa. Następnie plik <em>PracownikUzupelnianieInformacji.aar</em> umieszczamy w katalogu <strong>Apache Tomcat</strong>&#8216;a <em>webapps/axis2/WEB-INF/services</em>. Po chwili na konsoli <strong>Tomcat</strong>&#8216;a powinna pojawić sie informacja identyczna do tej:</p>
<pre class="prettyprint">
[INFO] Deploying Web service: PracownikUzupelnianieInformacji.aar</pre>
<p>Oznacza to, że nastąpiło wdrożenie naszego <strong>WebService</strong>&#8216;u. Hurrra!</p>
<p>Technika jaka została wykorzystana przy wdrożeniu to <strong>Hot Deployment</strong>. Jest to technika, która bez restartowania aplikacji (w tym wypadku <em>Axis2.war</em>) pozwala na dodawanie/usuwanie serwisów.</p>
<p>Ponownie weryfikacji tego faktu dokonać można przy pomocy interfejsu udostępnianego poprzez <strong>Axis</strong>&#8216;a przy pomocy przeglądarki. W sekcji <em>Services</em> powinien pojawić się nasz serwis wraz z metodami, jakie się na niego składają. Klikając na nazwie serwisu zostaniemy przekierowani na adres <a href="http://localhost:8080/axis2/services/PracownikUzupelnianieInformacji?wsdl">http://localhost:8080/axis2/services/PracownikUzupelnianieInformacji?wsdl</a>, gdzie &#8220;odnajdzie&#8221; się wcześniej zagubiony <em>WSDL</em>. Ze względu na pokaźną objętość pliku nie zostanie on tutaj zamieszczony, lecz warto we własnym zakresie zapoznać się z nim w celu weryfikacji wygenerowanych odwzorowań pomiędzy typami <strong>Java</strong>&#8216;owymi, a typami <strong>XML Schema</strong>.</p>
<p>Trudno przeoczyć, że ma miejsce tutaj pewnego rodzaju &#8220;magia&#8221;. <strong>Axis2</strong> posiadając jedynie skompilowane klasy dokonuje w sposób całkowicie automatyczny generacji pliku definicji <strong>WebService</strong>&#8216;u.</p>
<h3>Przygotowanie warstwy klienta</h3>
<p>Posiadając już gotowy, działający <strong>WebService</strong> możemy przystąpić do realizacji jego klienta. Warto być może raz jeszcze podkreślić fakt braku związku pomiędzy rodzajem implementacji serwera, a klienta. Równie dobrze zaprezentowane poniżej procedury mogłyby posłużyć do wygenerowania klienta dla innego serwisu. Prawdopodobnie jedyną różnicą byłoby zastosowanie alternatywnego adresu URL do <em>WSDL</em>&#8216;a.</p>
<p>W procesie przygotowania klienta wykorzystamy technikę pasywnej generacji kodu. Oznacza to, że dokonamy jednokrotnej generacji kodu dla <strong>WebService</strong>&#8216;u, który na późniejszym etapie będziemy modyfikować ręcznie, jeżeli oczywiście zajdzie taka potrzeba. Do tego celu użyjemy narzędzi linii poleceń dostarczonych razem ze standardową dystrybucją <strong>Axis2</strong>. Przed przystąpieniem do generacji należy jednak pamiętać o ustawieniu zmiennej środowiskowej <em>AXIS2_HOME</em> w taki sposób, by wskazywała ona lokalizację w której znajduje się rozpakowana dystrybucja <strong>Axis2</strong>. Warto także pomyśleć o zmodyfikowaniu zmiennej środowiskowej <em>PATH</em>, aby także wskazywała do katalogu w którym znajduje się narzędzie <em>WSDL2Java</em>. Gdy już tego dokonamy sama generacja kodu nie powinna przysporzyć nam już jakichkolwiek problemów.</p>
<p>W katalogu w którym planujemy umieszczenie wygenerowanego kodu źródłowego wykonujemy następujące polecenie</p>
<pre>WSDL2Java
  -uri http://localhost:8080/axis2/services/PracownikUzupelnianieInformacji?wsdl
  -d adb
  -s
  -S .</pre>
<p>Jedynym parametrem wywołania o którym wartało wspomnieć jest przełącznik <em>-d</em>. Jest on odpowiedzialny za wybór rodzaju wiązania danych (<em>databinding</em>), jakie będzie wykorzystywane w celu wygenerowania kodu. I tak <strong>Axis2</strong> dysponuje kilkoma alternatywnymi rozwiązaniami, które wspiera: <strong>XMLBeans</strong>, <strong>JiBX</strong>, <strong>JaxMe</strong>, referencyjną implementację <strong>JAXB</strong> oraz własną <strong>Axis Data Binding</strong>. My skorzystaliśmy z ostatniej z wymienionych, która jednocześnie jest wyborem domyślnym.</p>
<p>Jeżeli wszystko pójdzie zgodnie z oczekiwaniami w katalogu bieżącym powinniśmy odnaleźć wygenerowany kod. Trochę przerażającą kwestią może być jego objętość &#8211; wygenerowane klasy mają 230 kilobajtów. Przy 6 kilobajtach kodu serwera może być to wartość lekko &#8220;zniechęcająca&#8221;. Pocieszeniem w tym wypadku może być świadomość, że nie musieliśmy pisać tego kodu ręcznie. To niestety nie koniec niespodzianek &#8211; kod klienta do kompilacji oraz uruchomienia wymaga dosyć sporej ilości bibliotek (prawie 2,5 megabajta). Przy zastosowaniu bardziej skomplikowanych mechanizmów wiązania danych objętość zarówno kodu jaki i dodatkowych bibliotek może jeszcze wzrosnąć. Nie jest to bez znaczenia, jeżeli uruchamiany kod ma działać w warunkach ściśle ograniczonych zasobów &#8211; w tym wypadku z dużym prawdopodobieństwem możemy stwierdzić, że klient generowany automatycznie przez <strong>Axis</strong>&#8216;a nie będzie adekwatnym rozwiązaniem.</p>
<p>Mając już wygenerowanego klienta napiszemy krótki test, który będzie demonstrował sposób wywoływania <strong>WebService</strong>&#8216;u, jak i przy okazji zweryfikuje, że przygotowane przez nas rozwiązanie w rzeczywistości działa &#8211; zarówno serwer, jak i klient. Poniżej listing kodu źródłowego testu przygotowanego pod <strong>JUnit 4</strong>:</p>
<pre class="prettyprint">
public class PracownikUzupelnianieInformacjiStubTest {

  @Test
  public void testUzupelnijInformacjeOPracownikach() throws RemoteException, ObjectNotFoundExceptionException0, IdentyfikatorNotSetExceptionException1 {
    final PracownikUzupelnianieInformacjiStub pracownikUzupelnianieInformacjiStub = new PracownikUzupelnianieInformacjiStub();
    final UzupelnijInformacjeOPracownikach uzupelnijInformacjeOPracownikach = new UzupelnijInformacjeOPracownikach();        Pracownik[] pracownicy = new Pracownik[2];
    for (int i = 0; i &lt; 2; i++) {
      pracownicy[i] = new Pracownik();
      final Identyfikator identyfikator = new Identyfikator();
      identyfikator.setIdentyfikator(i + 1);
      pracownicy[i].setIdentyfikator(identyfikator);
    }

    uzupelnijInformacjeOPracownikach.setPracownicy(pracownicy);
    uzupelnijInformacjeOPracownikach.setGlebokoscUzupelniania(3);

    UzupelnijInformacjeOPracownikachResponse uzupelnijInformacjeOPracownikachResponse = pracownikUzupelnianieInformacjiStub.uzupelnijInformacjeOPracownikach(uzupelnijInformacjeOPracownikach);

    for (final Pracownik pracownik : uzupelnijInformacjeOPracownikachResponse.get_return()) {
      weryfikujPracownika(pracownik);
    }
  }

  private void weryfikujPracownika(Pracownik pracownik) {
    Assert.assertTrue(pracownik.getIdentyfikator().getIdentyfikator() &gt;= 0);
    Assert.assertEquals("Pracownik[X].imie", pracownik.getImie().replaceAll("d+", "X"));
    Assert.assertEquals("Pracownik[X].nazwisko", pracownik.getNazwisko().replaceAll("d+", "X"));
    Assert.assertTrue(pracownik.getRokUrodzenia() &gt;= 1935);

    final Pracownik[] podwladni = pracownik.getPodwladni();

    if (podwladni == null) {
      return;
    }

    for (final Pracownik podwladny : podwladni) {
      if (podwladny != null) {
        weryfikujPracownika(podwladny);
      }
    }
  }
}</pre>
<p>Jak łatwo można zauważyć całość logiki odpowiedzialnej za komunikowanie się z <strong>WebService</strong>&#8216;em została przed nami ukryta. Naszą odpowiedzialność pozostaje jedynie zapewnienie odpowiedniej obsługi wyjątku typu <strong>RemoteException</strong>.</p>
<h3>Konkluzja</h3>
<p>W mojej opinii <strong>Axis2</strong> nie jest jeszcze rozwiązaniem idealnym (posiada wciąż wiele swoich problemów), lecz w porównaniu do konkurencji &#8211; w tym także do produktów komercyjnych &#8211; stanowi godną rozważenie alternatywę. Produkt ten pozostawia po sobie pozytywne wrażenie &#8211; szczególnie długa lista rozszerzeń może determinować jego zastosowanie.</p>
<h3>Dodatkowe informacje dla szczególnie zainteresowanych ;)</h3>
<pre>
<a href="http://www.w3.org/2002/ws/">http://www.w3.org/2002/ws/</a>

<a href="http://ws.apache.org/axis2/">http://ws.apache.org/axis2/</a>

<a href="http://wiki.apache.org/ws/FrontPage/Axis2/">http://wiki.apache.org/ws/FrontPage/Axis2/</a></pre>
]]></content:encoded>
			<wfw:commentRss>http://j2ee.pl/2007/08/25/tworzenie-webserviceow-z-wykorzystaniem-axis2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
