13 08

background image

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 323

13

Firma-firma

Czytelnik wie już dużo o XML-u. Poznał interfejsy SAX, DOM i JDOM, znajome mu są struktury
publikacji i zaawansowane transformacje, jak również model XML-RPC; zna także zagadnienia
związane z zastosowaniem XML-a w procesach konfiguracji oraz z wykorzystaniem tego języka
jako źródła danych; potrafi również tworzyć dane XML z programów w Javie. W niniejszym
rozdziale zostanie omówiony bardzo modny temat, a mianowicie zastosowanie XML-a w
aplikacjach typu firma-firma. Przedsiębiorstwa wkroczyły w erę internetową i właściwa komunikacja
stała się najważniejszym warunkiem prowadzenia handlu. Wiele firm przywiązuje większą wagę do
procesów komunikacyjnych niż... do własnych produktów. Agresywne kampanie online i aplikacje
e-biznesowe mogą przyczynić się do pokonania konkurencji, która może nawet oferować
atrakcyjniejsze produkty. Ogromną rolę w pojęciu „firma-firma” odgrywa XML. Język ten
stanowi standardowy sposób reprezentacji danych i właśnie dzięki niemu firmy wykorzystujące
różne aplikacje, systemy i języki programowania mają możliwość komunikowania się ze sobą.

W niniejszym rozdziale Czytelnik dowie się, w jaki sposób za pomocą XML-a można uzyskać
taką właśnie możliwość porozumienia pomiędzy różnymi aplikacjami; na potrzeby rozdziału zostaną
nawet stworzone wyimaginowane firmy. Tym razem XML nie posłuży do wymiany informacji
pomiędzy składnikami jednej aplikacji ani też jako źródło danych, ale do komunikacji pomiędzy
różnymi aplikacjami. Najpierw zostanie zaprezentowana Biblioteka Publiczna NaNiby, której
dostawcy będą mogli wprowadzać nowe tytuły w trybie online. Książki będą następnie dodawane
do składnicy danych biblioteki do późniejszego wykorzystania. Niestety, w dzisiejszych czasach
trudno o dobrych programistów Javy, a więc nasza biblioteka będzie opierała swoje działanie na
programie CGI napisanym w Perlu. Nowe książki wpisywane online są sortowane przez skrypt
właśnie w tym języku.

Będzie też druga firma, KsiegarniaTechniczna.com. W tej księgarni sprzedaje się w systemie online
— w porozumieniu z innymi dużymi księgarniami — książki o tematyce technicznej i komputero-
wej (takie jak ta). Ostatnio podpisano umowę z Biblioteką Publiczną NaNiby, zgodnie z którą firma
będzie uzyskiwała książki od tej biblioteki na specjalnych warunkach. KsiegarniaTechniczna.com
opłaci koszty dostawy i administracyjne, zaś biblioteka zamówi dodatkowe egzemplarze książek
po specjalnej, obniżonej cenie; te dodatkowe książki sprzeda następnie KsiegarniaTech-
niczna.com. KsiegarniaTechniczna.com musi mieć dostęp do danych wprowadzanych
w Bibliotece Publicznej NaNiby przez dostawców, tak aby wiedzieć o nowych tytułach i móc je
reklamować u siebie. Jednakże nie wiadomo, w jaki sposób uzyskać dostęp do danych systemu bi-

background image

324

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 324

blioteki opartego na Perlu. Co więcej, pomiędzy obiema firmami nie istnieją chronione połączenia
sieciowe, a więc konieczne jest wykorzystanie zwyczajnego protokołu HTTP.

Czytelnik będzie mógł spojrzeć na te aplikacje z punktu widzenia klientów KsiegarniaTech-
niczna.com. Księgarnia oferuje produkty osobom aktywnym w Internecie, a więc chce ogłaszać się
w witrynach w rodzaju Netscape Netcenter; chce także, aby klienci mogli w prosty sposób uzyskać
informacje z ich witryny o nowych ofertach. Jednakże, podobnie jak w przypadku Biblioteki
Publicznej NaNiby, KsiegarniaTechniczna.com nie posiada informacji o tym, jak to zrobić.
Przedstawiciele grupy Netscape Netcenter poinformowali programistów księgarni, że na potrzeby
takiego reklamowania się najlepiej nadaje się RSS (Rich Site Summary). Ale programiści
księgarni nawet nie wiedzą, czym jest RSS!

Zaczniemy od Biblioteki Publicznej NaNiby — przyjrzymy się, jak zbudowany jest ich system na-
pisany w Perlu. Następnie przejdziemy do firmy KsiegarniaTechniczna.com, a jeszcze później do
klientów tej księgarni. Zobaczymy, jak pomiędzy tymi wszystkimi stronami stworzyć komunika-
cję opartą na języku XML.

Biblioteka Publiczna NaNiby

Tworzenie systemu typu firma-firma rozpoczniemy od zbadania, jaki stan rzeczy zastaliśmy w bi-
bliotece. Zanim jednak przejdziemy do samego kodu aplikacji, musimy poznać wymagania biblio-
teki (aby nie tworzyć systemu, którego nie będzie można potem obsłużyć).

Określenie wymagań

Często dobre rozwiązanie nie oznacza jeszcze — w przypadku określonej firmy — rozwiązania
zgodnego z wymaganiami. Świetnym przykładem jest tutaj Biblioteka Publiczna NaNiby — pro-
blemy tej biblioteki i firmy KsiegarniaTechniczna.com można byłoby rozwiązać za pomocą
serwletów Javy działających po obu stronach. Jednakże nie zostałyby wówczas zaspokojone
wymagania biblioteki. A więc najpierw należy przyjrzeć się właśnie wymaganiom:

• rozwiązanie musi być napisane w Perlu; w bibliotece nie ma programistów Javy;
• rozwiązanie nie może wymagać instalacji nowego oprogramowania czy bibliotek;
• rozwiązanie nie może wpłynąć na istniejący system zamawiania (nie może być zmian

w interfejsie).

Nie są to może jakieś zaporowe wymagania, ale na pewno zmuszają do ponownego przeanalizo-
wania problemu. Nie wolno nam korzystać z Javy. Oczywiście, ponieważ ta książka jest o XML-u,
Czytelnik może się domyślać, że dane o nowych książkach będą zapisywane w formacie XML,
następnie przekazywane klientom protokołem HTTP i wykorzystywane w dowolny sposób. Tak,
i jest to o wiele lepsze rozwiązanie niż komunikacja pomiędzy serwletami; XML może zostać uży-
ty w dowolnej firmie lub u dowolnego klienta i nie trzeba „przywiązywać” biblioteki (i wszystkich
jej książek) do jednej, określonej firmy. I w ten sposób zostało nakreślone zadanie związane
z aktualizacją systemu biblioteki — zachować wpisane informacje w postaci kodu XML, a następ-
nie stworzyć klientom możliwość dostępu do tych danych poprzez protokół HTTP.

background image

Biblioteka Publiczna NaNiby

325

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 325

Wprowadzanie książek

Po pierwsze trzeba poznać istniejący interfejs, za pomocą którego dostawcy wprowadzają nowe
książki do systemu. W przykładzie 13.1 pokazano, jak zbudowany jest sam statyczny formularz.

Przykład 13.1. Statyczny interfejs Biblioteki Publicznej NaNiby w HTML-u

<html>

<head>
<title>Biblioteka Publiczna NaNiby: Wprowadzanie książek</title>
<style>
<!--
body { font-family: Arial }
h1 { color: #000080 }
-->
</style>
</head>

<body link="#FFFF00" vlink="#FFFF00" alink="#FFFF00">
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tr>
<td width="15%" bgcolor="#000080" valign="top" align="center">
<b><i>
<font color="#FFFFFF" size="4">Opcje</font>
</i></b>
<p><b>
<font color="#FFFFFF">
<a href="/javaxml/foobar">Menu Główne</a>
</font>
</p></b>
<p><b>
<font color="#FFFFFF">
<a href="/javaxml/foobar/catalog.html">Katalog</a>
</font>
</b></p>
<p><b>
<i><font color="#FFFF00">Wprowadzanie książek</font></i>
</b></p>
<p><b>
<font color="#FFFFFF">
<a href="/javaxml/foobar/logout.html">Wylogowanie</a>
</font>
</p></td>
<td width="*" valign="top" align="center">
<h1 align="center">Biblioteka Publiczna NaNiby</h1>
<h3 align="center"><i>- Dodawanie książek -</i></h3>

<!-- Poniżej ścieżka do katalogu i skryptu CGI, którym zajmiemy się w

następnej kolejności -->

<form method="POST" action="/cgi/addBook.pl">

<table border="0" cellpadding="5" width="100%">
<tr>
<td width="100%" valign="top" align="center" colspan="2">
Tytuł&nbsp;
<input type="text" name="title" size="20">
<hr width="85%" />
</td>
</tr>
<tr>

background image

326

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 326

<td width="50%" valign="top" align="right">Autor&nbsp;
<input type="text" name="author" size="20">
</td>
<td width="50%" valign="top" align="left">Temat&nbsp;
<select size="1" name="subject">
<option>Beletrystyka</option>
<option>Biografie</option>
<option>Nauka</option>
<option>Przemysł</option>
<option>Komputery</option>
</select></td>
</tr>
<tr>
<td width="50%" valign="top" align="right">Wydawca&nbsp;
<input type="text" name="publisher" size="20">
</td>
<td width="50%" valign="top" align="left">ISBN&nbsp;
<input type="text" name="isbn" size="20">
</td>
</tr>
<tr>
<td width="50%" valign="top" align="right">Cena&nbsp;
<input type="text" name="price" size="20">
</td>
<td width="50%" valign="top" align="left">Stron&nbsp;
<input type="text" name="numPages" size="20">
</td>
</tr>
<tr>
<td width="100%" valign="top" align="center" colspan="2">
Opis&nbsp;
<textarea rows="2" name="description" cols="20"></textarea>
</td>
</tr>
</table>
<p>
<input type="submit" value="Dodaj książkę" name="addBook">
<input type="reset" value="Wyczyść formularz" name="reset">
<input type="button" value="Anuluj" name="cancel">
</p>
</form>
</td>
</tr>
</table>
</body>

</html>

Powyższy plik, zachowany jako addBooks.html, umożliwia wprowadzenie nowych książek przy-
syłanych do biblioteki.

W tym rozdziale zostanie wydrukowany pełny kod wszystkich opisywanych przykła-
dów, tak aby Czytelnik mógł sam stworzyć przykładową aplikację i dokładnie zaznajo-
mić się z procesem uruchamiania komunikacji XML pomiędzy firmami. Możliwe jest
też obejrzenie działających przykładów pod adresem http://www.newInstance.com.
Stamtąd, jak również spod adresu http://www.oreilly.com/catalog/javaxml/, można
także pobrać przykładowe pliki. W tym rozdziale założono, że Czytelnik użyje nazw
plików zgodnych z opisywanymi; w przeciwnym razie trzeba odpowiednio dostosować
kod (miejsca wymagające takich zmian odpowiednio zaznaczono).

background image

Biblioteka Publiczna NaNiby

327

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 327

Po załadowaniu powyższego przykładu do przeglądarki, Czytelnik otrzyma wynik przypominający
ten na rysunku 13.1. Tutaj nie będą omawiane pozostałe pozycje menu, ale przecież dostawca mo-
że chcieć przejrzeć katalog biblioteki, przejść do menu głównego czy wylogować się — wszystkie
te opcje muszą więc znaleźć się w zasięgu ręki.

Rysunek 13.1. Interfejs HTML biblioteki

Formularz taki pozwala dostawcy wprowadzić szczegółowe informacje o każdej książce przesyła-
nej do biblioteki. Wprowadzane są następujące dane: tytuł, autor, wydawca, liczba stron, cena, nu-
mer ISBN, opis, a także kategoria tematyczna książki.

Po wprowadzeniu informacji formularz przesyłany jest do skryptu CGI:

<form method="POST" action="/cgi/addBook.pl">

Skrypt ten ma następnie zwrócić dane XML. Najprościej byłoby załadować bibliotekę Perla do
obsługi przetwarzania XML, np. Xerces-Perl; należy jednak pamiętać o tym, że jedno z wymagań
brzmi: żadnych nowych bibliotek i oprogramowania. Takie ograniczenie może wydawać się
głupie, ale trzeba pamiętać, że w wielu firmach oprogramowanie produkcyjne traktuje się w spo-
sób bardzo mało elastyczny. Biblioteka Publiczna NaNiby ma „zaistnieć” w Internecie, ale nie mo-
żemy przeznaczyć na to żadnych dodatkowych zasobów i środków.

Na szczęście naszym zadaniem jest tylko uzyskać dane XML. Można to zrobić w dość łatwy spo-
sób — „brutalnie” generując pliki z informacjami wprowadzonymi do formularza. Ponieważ wszy-
stkie dotychczasowe informacje i tak mają być zachowywane, zamiast tworzyć nowe pliki,
wystarczy dołączyć nowe informacje do plików już istniejących. Dla programistów Javy napisanie

background image

328

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 328

odpowiedniego programu w Perlu jest banalnym zadaniem — cały kod został zamieszczony w
przykładzie 13.2.

Przykład 13.2. Skrypt Perl CGI generujący wpisy XML z wprowadzonych książek

#!/usr/local/bin/perl

$baseDir = "/usr/local/projects/javaxml/foobar/books/";
$filename = "books.txt";

$bookFile = $baseDir . $filename;

# Pobieramy dane od użytkownika.
use CGI;
$query = new CGI;

$title = $query->param('title');
$author = $query->param('author');
$subject = $query->param('subject');
$publisher = $query->param('publisher');
$isbn = $query->param('isbn');
$price = $query->param('price');
$numPages = $query->param('numPages');
$description = $query->param('description');

# Zachowujemy dane w pliku XML.
if (open(FILE, ">>" . $bookFile)) {
print FILE "<book subject=\"" . $subject . "\">\n";
print FILE " <title><![CDATA[" . $title . "]]></title>\n";
print FILE " <author><![CDATA[" . $author . "]]></author>\n";
print FILE " <publisher><![CDATA[" . $publisher . "]]></publisher>\n";
print FILE " <numPages>" . $numPages . "</numPages>\n";
print FILE " <saleDetails>\n";
print FILE " <isbn>" . $isbn . "</isbn>\n";
print FILE " <price>" . $price . "</price>\n";
print FILE " </saleDetails>\n";
print FILE " <description><![CDATA[" . $description . "]]></description>\n";
print FILE "</book>\n\n";

# Wysyłamy potwierdzenie użytkownikowi.
print <<"EOF";
Content-type: text/html

<html>
<head>
<title>Biblioteka Publiczna NaNiby: Potwierdzenie</title>
</head>
<body>
<h1 align="center">Książka została dodana</h1>
<p align="center">
Dziękujemy. Książka została dodana do Biblioteki.
</p>
</body>
</html>
EOF

} else {
print <<"EOF";
Content-type: text/html

<html>
<head>

background image

Biblioteka Publiczna NaNiby

329

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 329

<title>Biblioteka Publiczna NaNiby: Błąd</title>
</head>
<body>
<h1 align="center">Błąd przy dodawaniu książki.</h1>
<p align="center">
Książka NIE została wprowadzona do biblioteki.
</p>
</body>
</html>
EOF
}

close (FILE);

Powyższy program, zachowany jako addBook.pl, uruchamiany jest po wysłaniu formularza. Skrypt
definiuje nazwę pliku, do którego mają zostać zapisane dane, a następnie przypisuje parametry po-
brane z formularza zmiennym lokalnym:

$title = $query->param('title');
$author = $query->param('author');
$subject = $query->param('subject');
$publisher = $query->param('publisher');
$isbn = $query->param('isbn');
$price = $query->param('price');
$numPages = $query->param('numPages');
$description = $query->param('description');

Kiedy już wartości te są dostępne, skrypt otwiera plik zdefiniowany wcześniej w trybie do dopisywa-
nia (symbol >> poprzedzający nazwę pliku) i na jego końcu zapisuje dane sformatowane jako XML:

print FILE "<book subject=\"" . $subject . "\">\n";
print FILE " <title><![CDATA[" . $title . "]]></title>\n";
print FILE " <author><![CDATA[" . $author . "]]></author>\n";
print FILE " <publisher><![CDATA[" . $publisher . "]]></publisher>\n";
print FILE " <numPages>" . $numPages . "</numPages>\n";
print FILE " <saleDetails>\n";
print FILE " <isbn>" . $isbn . "</isbn>\n";
print FILE " <price>" . $price . "</price>\n";
print FILE " </saleDetails>\n";
print FILE " <description><![CDATA[" . $description . "]]></description>\n";
print FILE "</book>\n\n";

Temat wykorzystywany jest jako atrybut elementu znajdującego się wyżej w hierarchii (book),
natomiast pozostałe informacje zostają wprowadzone jako poszczególne elementy. Ponieważ pola
zawierające tytuł, nazwisko autora, opis i nazwę wydawcy książki mogą zawierać cudzysłowy, apo-
strofy, „ampersandy” i inne znaki wymagające wstawienia ich w sekwencje unikowe, dane te zam-
kniemy w sekcji CDATA, co zwolni nas z konieczności znoszenia specjalnych znaczeń tych znaków.

Ponadto powinniśmy zauważyć, że nie tworzymy deklaracji XML ani elementu głównego (w je-
dnym pliku będą zawarte informacje o wielu książkach). Ponieważ sprawdzenie, czy plik istnieje,
zapisanie deklaracji i elementu głównego, jeśli nie istnieje, a następnie zapisanie elementu kończą-
cego (który po każdej nowej porcji informacji będzie musiał zostać nadpisany) jest nieco kłopotli-
we, pozostawimy ten plik w takiej postaci, w jakiej jest — jako fragment dokumentu XML. Na
przykład tak wyglądałby plik po wprowadzeniu dwóch książek:

<book subject="Computers">
<title><![CDATA[Java Servlet Programming]]></title>
<author><![CDATA[Jason Hunter]]</author>
<publisher><![CDATA[O'Reilly & Associates]]></publisher>
<numPages>528</numPages>
<saleDetails>

background image

330

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 330

<isbn>156592391X</isbn>
<price>36.95</price>
</saleDetails>
<description><![CDATA[Doskonałe wprowadzenie do serwletów Javy i
różnych mechanizmów komunikacyjnych.]]></description>
</book>

<book subject="Fiction">
<title><![CDATA[Second Foundation]]></title>
<author><![CDATA[Isaac Asimov]]</author>
<publisher><![CDATA[Bantam Books]]></publisher>
<numPages>279</numPages>
<saleDetails>
<isbn>0553293362</isbn>
<price>5.59</price>
</saleDetails>
<description><![CDATA[Po zagarnięciu Pierwszej Fundacji tylko Druga Fundacja

mogła zapobiec całkowitej destrukcji.]]></description>

</book>

Może nie jest to kompletny dokument XML, ale sam ten fragment jest sformatowany poprawnie
i mógłby zostać wstawiony do dokumentu XML zawierającego już nagłówek i element główny.
I tak właśnie zrobimy, kiedy za chwilę zajmiemy się mechanizmem wyświetlającym listę książek.

Reszta skryptu zwraca odpowiednie dane HTML w zależności od tego, czy dodawanie książki się
powiodło, czy nie. W pierwszym przypadku dostawca zobaczy proste potwierdzenie, takie jak na
rysunku 13.2.

Rysunek 13.2. Komunikat potwierdzający dodanie książki

Teraz można już wykorzystać ten fragment dokumentu do udzielania odpowiednich informacji
stronom żądającym.

Wyświetlanie listy dostępnych książek

Do wyświetlenia listy nowych książek znów posłuży Perl. Załóżmy, że jakaś inna porcja aplikacji
biblioteki okresowo odczytuje dane XML i aktualizuje katalog. Ten składnik aplikacji byłby
odpowiedzialny również za usuwanie wpisów w naszym pliku, tak aby książki już wprowadzone
do katalogu nie były klasyfikowane jako „nowe”. Zadanie dla naszego drugiego skryptu w Perlu
jest więc następujące: odczytać fragment kodu XML i dodać dane do dokumentu wyświetlanego
na ekranie. Jak już było wspomniane, konieczne jest także dodanie deklaracji XML i elementu

background image

Biblioteka Publiczna NaNiby

331

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 331

głównego, „otaczającego” dostarczoną zawartość. Nowy skrypt (przykład 13.3) odczytuje plik utwo-
rzony przez addBook.pl i wyświetla odpowiednią zawartość po otrzymaniu żądania przez HTTP.

Przykład 13.3. Skrypt Perl CGI wyświetlający dokument XML z nowymi książkami

#!/usr/local/bin/perl

$baseDir = "/usr/local/projects/javaxml/foobar/books/";
$filename = "books.txt";

$bookFile = $baseDir . $filename;

# Najpierw otwieramy plik.
open(FILE, $bookFile) || die "Could not open $bookFile.\n";

# Przekazujemy przeglądarce informacje o rodzaju przesyłanych danych.
print "Content-type: text/plain\n\n";

# Wyświetlamy nagłówek i element główny XML.
print "<?xml version=\"1.0\"?>\n";
print "<books>\n";

# Wyświetlamy książki.
while (<FILE>) {
print "$_";
}

# Zamykamy element główny.
print "</books>\n";

close(FILE);

Powyższy skrypt, zachowany jako supplyBooks.pl, przyjmie żądanie, odczyta plik stworzony przez
addBook.pl i wyświetli dane XML po żądaniu HTTP. Przykładowy wynik (z dodanymi książkami)
można obejrzeć na rysunku 13.3.

background image

332

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 332

Rysunek 13.3. Wynik działania skryptu supplyBooks.pl

Jak widać, prostą aplikację w Perlu łatwo można zamienić w składnik, który potrafi dostarczyć
użyteczne informacje klientom — takim jak księgarnia KsiegarniaTechniczna.com. Zrobiliśmy to
bez instalacji nowego oprogramowania, bez zmiany architektury systemu lub aplikacji i bez pisa-
nia choćby jednej linijki kodu w Javie!

KsiegarniaTechniczna.com

Biblioteka Publiczna NaNiby umożliwia już uzyskanie dostępu do danych o nowych książkach
w formacie XML. Teraz KsiegarniaTechniczna.com jest już bliska osiągnięcia zamierzonego celu
— dostarczyć aktualne informacje swoim klientom. W firmie tej już dawno wykorzystuje się Javę
do budowania aplikacji, co bardzo uprości proces uzyskiwania dostępu i korzystania z danych XML
oferowanych przez bibliotekę — Java świetnie obsługuje XML, o czym zresztą przekonuje cała
niniejsza książka. Najpierw chcemy umożliwić wyświetlanie w firmie KsiegarniaTechniczna.com
danych dotyczących nowych książek, a następnie udostępnić te informacje klientom tej firmy.

Filtrowanie danych XML

W firmie KsiegarniaTechniczna.com mają być wyświetlane wyłącznie dane o książkach technicz-
nych. Jak zapewne Czytelnik pamięta, Biblioteka Publiczna NaNiby pozwalała na wprowadzanie
książek o zróżnicowanej tematyce; KsiegarniaTechniczna.com akceptuje wyłącznie książki o pro-
blematyce informatycznej. Na szczęście, odpowiednia informacja jest zawarta w atrybucie sub-
ject elementu book. Najpierw należy więc odfiltrować wszystkie książki, których tematem nie
jest „Computers”. Kiedy już uzyskamy w ten sposób książki o tematyce informatycznej, musimy
je sformatować do postaci strony HTML, którą pokażemy klientom odwiedzającym witrynę firmy
KsiegarniaTechniczna.com.

background image

KsiegarniaTechniczna.com

333

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 333

Tutaj nie będziemy korzystali ze strony statycznej, ponieważ strona z nowymi pozycjami musi
zostać wygenerowana przy każdej próbie jej pobrania. Oczywiście, tym razem do obsługi takich
żądań wykorzystamy serwlet. Do konwersji danych XML z biblioteki na postać HTML świetnie
nadawałby się Apache Cocoon, ale pracownicy firmy KsiegarniaTechniczna.com muszą całe zada-
nie wykonać jak najszybciej i na razie nie chcą wprowadzać tak dużych zmian w istniejącym sys-
temie. Wolą wykorzystać parsery i procesory XML, a dopiero w drugiej fazie wdrażania zainsta-
lować Cocoon. A więc trzeba obsłużyć konwersję XML-HTML, a oprócz tego jeszcze filtrowanie
i dodawanie elementów prezentacyjnych (np. logo firmy czy pasek menu).

Ale jeśli Czytelnik przywoła całą wiedzę o XML-u i XSL-u, to być może przypomni sobie, że
nawet bez Cocoona można przekształcać dokumenty XML na format HTML-a — za pomocą
arkuszy XSL. W trakcie transformacji można również odfiltrować książki o tematyce innej niż
komputerowa. Pamiętając o tym wszystkim, możemy już stworzyć arkusz stylu, który zostanie
zastosowany do dokumentu przesłanego z Biblioteki Publicznej NaNiby. Początkowy fragment ta-
kiego arkusza, obsługujący generację dokumentu HTML, został zamieszczony w przykładzie 13.4.

Przykład 13.4. Arkusz stylu dla danych otrzymywanych z Biblioteki Publicznej NaNiby

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
>

<xsl:template match="books">
<html>
<head>
<title>Księgarnia Techniczna - Twój sklep z literaturą

komputerową</title>

</head>
<body

background="http://newInstance.com/javaxml/techbooks/images/background
.gif"

link="#FFFFFF" vlink="#FFFFFF" alink="#FFFFFF">
<h1 align="center">
<font face="Arial" color="#00659C">
&lt;KsiegarniaTechniczna.com&gt;
</font>
</h1>
<p align="center">
<i><b>Twoje źródło książek o tematyce komputerowej i

technicznej.</b></i>

</p>
<p align="center">
<b><font size="4" color="#00659C">
<u>Nowe pozycje</u>
</font></b>
</p>
<table border="0" cellpadding="5" cellspacing="5">
<tr>
<td valign="top" align="center" nowrap="nowrap" width="115">
<p align="center">
<font color="#FFFFFF"><b>
<a href="http://newInstance.com/javaxml/techbooks/">Strona

główna</a>

</b></font>
</p>
<p align="center">
<font color="#FFFFFF"><b>

background image

334

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 334

<a

href="http://newInstance.com/javaxml/techbooks/current.html">Obecne
pozycje</a>

</b></font>
</p>
<p align="center">
<b><font color="#FFFFFF">
<i>Nowe pozycje</i>
</font></b>
</p>
<p align="center">
<font color="#FFFFFF"><b>
<a

href="http://newInstance.com/javaxml/techbooks/contact.html">Kontakt</
a>

</b></font>
</p>
</td>
<td valign="top" align="left">
<table border="0" cellpadding="5" cellspacing="5">
<tr>
<td width="450" align="left" valign="top">
<p>
<b>
Witamy w firmie <font

face="courier">KsiegarniaTechniczna.com</font>,

oferującej książki o tematyce komputerowej i technicznej.
Po lewej stronie zamieszczono najnowsze tytuły. Aby nabyć którąś

z tych wspaniałych książek, wystarczy kliknąć odsyłacz &quot;Kup
książkę!&quot; co spowoduje jej przeniesienie do koszyka. Miłych
zakupów!

</b>
</p>
<p>
<b>
Można także przejrzeć nasze wcześniejsze tytuły, zajrzeć do

informacji

o sklepie, albo skontaktować się z nami. Wszystkie niezbędne

odsyłacze

znajdują się po lewej stronie. Dziękujemy za zakupy u nas!
</b>
</p>
</td>
<td align="left">

<!-- Tutaj tworzymy zawartość dla każdej nowej *komputerowej*

książki -->

</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

background image

KsiegarniaTechniczna.com

335

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 335

Co prawda nie zostały jeszcze odfiltrowane przychodzące dane XML (nie zostały również prze-
kształcone), ale interfejs HTML przedstawiany użytkownikowi jest już gotowy. Często o wiele
prościej jest najpierw zająć się tymi „prezentacyjnymi drobiazgami”, a dopiero potem samą logiką
transformacji.

Przy tworzeniu arkuszy XSL, szczególnie na potrzeby aplikacji WWW, należy zawsze
testować wynik poprzez procesor XSLT, wywołując go z wiersza poleceń. W ten spo-
sób zostanie zagwarantowane, że na każdym etapie tworzenia dokument przetwarzany
jest zgodnie z oczekiwaniami. O wiele trudniej usuwać błędy w dużym, gotowym już
arkuszu stylu. Informacje o tym, jak korzystać z procesora Apache Xalan z wiersza
poleceń, zostały zawarte w rozdziale 7. W tym konkretnym przypadku można pobrać
plik supplyBooks.pl za pomocą przeglądarki, zachować wynik jego działania w pliku
XML i wtedy przetestować arkusz stylu.

Podobnie jak w przypadku aplikacji w Bibliotece Publicznej NaNiby, po lewej stronie tworzone
jest menu z odsyłaczami do innych części aplikacji; umieszczony jest również krótki opis firmy i jej
oferty. Natomiast po prawej stronie pozostawiliśmy miejsce na nowe pozycje książkowe.

Przed odfiltrowaniem zawartości trzeba dodać szablon wyświetlający zawartość HTML z jednego
elementu book. Wpis będzie wyglądał mniej więcej tak:

<book subject="Computers">
<title><![CDATA[Running Linux]]></title>
<author><![CDATA[Matt Welsh]]</author>
<publisher><![CDATA[O'Reilly & Associates]]></publisher>
<numPages>630</numPages>
<saleDetails>
<isbn>1565921518</isbn>
<price>29.95</price>
</saleDetails>
<description><![CDATA[Zgodnie z tradycją tytułów O'Reilly, książka Running
Linux oferuje przejrzyste instrukcje krok po kroku, zawsze dostarczające
Czytelnikowi akurat tyle informacji, ile potrzeba.]]></description>
</book>

Takie dane należy przekształcić w kod HTML za pomocą następującego szablonu XSL:

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
>

<xsl:template match="books">
<!-- Interfejs użytkownika -->
</xsl:template>

<xsl:template match="book">
<table border="0" cellspacing="1" bgcolor="#000000">
<tr>
<td>
<table border="0" cellpadding="3" cellspacing="0">
<tr>
<td width="100%" bgcolor="#00659C" nowrap="nowrap" align="center">
<b><font color="#FFFFFF">
<xsl:value-of select="title" />
</font></b>
</td>

background image

336

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 336

</tr>
<tr>
<td width="100%" align="center" nowrap="nowrap" bgcolor="#FFFFFF">
<font color="#000000"><b>
Autor: <xsl:value-of select="author" /><br />
Wydawca: <xsl:value-of select="publisher" /><br />
Stron: <xsl:value-of select="numPages" /><br />
Cena: <xsl:value-of select="saleDetails/price" /><br />
<br />
</b></font>
<xsl:element name="a">
<xsl:attribute name="href">/servlets/BuyBookServlet?isbn=
=<xsl:value-of select="saleDetails/isbn" />
</xsl:attribute>
<font color="#00659C">Kup książkę!</font>
</xsl:element>
</td>
</tr>
</table>
</td>
</tr>
</table>
<br />
</xsl:template>

</xsl:stylesheet>

Szablon dopasowuje element book, a następnie tworzy tabelę z nagłówkiem w jednym wierszu
i zawartością w drugim. Cała tabela umieszczona jest wewnątrz innej tabeli, dzięki czemu w prze-
glądarce ta pierwsza tabela sprawia wrażenie otoczonej czarną ramką. Tytuł wstawiany jest do
nagłówka tabeli, a informacje o książce (autor, wydawca, liczba stron i cena) do zawartości tabeli.
Jest tam również odsyłacz do serwleta Javy BuyBookServlet, za pomocą którego można
w prosty sposób zakupić daną książkę. Jako argument wywołania serwleta podawany jest numer
ISBN tej książki.

W arkuszu XSL trzeba sprawdzić, czy wiersz opisujący użycie BuyBookServlet
oraz wiersz z elementem xsl:value-of tworzą tak naprawdę jedną linijkę. W prze-

ciwnym razie do wynikowego adresu URL mogłyby „przedostać się” spacje i znaki no-
wego wiersza i serwlet otrzymałby niepoprawne dane. W przedstawionym arkuszu stylów,
w wyniku łamania tekstu w druku, te informacje zostały rozbite na dwa wiersze.

Teraz trzeba jeszcze zagwarantować, że nowy szablon zostanie zastosowany i że zostaną do niego
przekazane wyłącznie książki o tematyce „Computers”. Wartość atrybutu subject poznamy po-
przez odwołanie się do niego za pomocą symbolu @; filtrowanie nastąpi poprzez atrybut select
elementu xsl:apply-templates:

</td>
<td align="left">

<!-- Tutaj tworzymy zawartość dla każdej nowej *komputerowej*

książki -->

<xsl:apply-templates select="book[@subject='Computers']" />

</td>
</tr>
</table>

background image

KsiegarniaTechniczna.com

337

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 337

Odwołujemy się do wartości atrybutu i porównujemy go z łańcuchem znaków (w apostrofach
— to dlatego, że całe wyrażenie XPath znajduje się w cudzysłowach). Ponieważ „obrabiamy”
atrybut elementu zagnieżdżonego, odwołujemy się do niego przez nazwę i otaczamy wyrażenie
związane z jego atrybutem nawiasami kwadratowymi. W ten sposób gwarantujemy, że szablon
zostanie zastosowany tylko na książkach o tematyce „Computers”. Po stworzeniu arkusza stylów
można go zachować jako computerBooks.xsl i odwoływać się do niego poprzez serwlet Javy, który
zostanie przedstawiony poniżej.

XSLT poprzez serwlet

Arkusz stylu jest gotowy. Potrzebny jest jeszcze kod w Javie, który spowoduje zastosowanie tego
arkusza na danych z biblioteki. Dostęp do danych odbędzie się za pośrednictwem klasy Javy URL,
poprzez którą wyślemy żądanie HTTP do systemu biblioteki. Po tym wszystkim pozostanie już
tylko wykonać faktyczną transformację z poziomu programu. W przykładzie 13.5 przedstawiono
kod serwleta ładującego dane XML z biblioteki i ukazującego, w którym miejscu znajdzie się kod
przekształcający (wykonujący transformację).

Przykład 13.5. Serwlet Javy przekształcający informacje o książkach na postać kodu HTML

package com.techbooks;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import javax.servlet.*;
import javax.servlet.http.*;

public class ListBooksServlet extends HttpServlet {

/** Host, z którego pobierzemy listę książek */
private static final String hostname = "newInstance.com";
/** Port powyższego hosta */
private static final int portNumber = 80;
/** Plik (ścieżka URI) zawierający listę książek */
private static final String file = "/cgi/supplyBooks.pl";

/** Arkusz stylu, według którego przekształcimy XML */
private static final String stylesheet =

"/home/client/java/newinstance/www/javaxml/techbooks/XSL/computerBooks
.xsl";

public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

res.setContentType("text/html");

// Łączymy się w celu pobrania listy książek
URL getBooksURL = new URL("http", hostname, portNumber, file);
InputStream in = getBooksURL.openStream();

// Przekształcamy dane XML za pomocą arkusza stylu
}

}

background image

338

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 338

Ten prosty serwlet wysyła żądanie HTTP do biblioteki i otrzymuje odpowiedź w języku XML
w postaci strumienia InputStream

1

. Strumień zostanie następnie wykorzystany jako parametr

procesora XSLT oraz jako baza do przekształcenia przez arkusz stylu zdefiniowany w serwlecie
jako statyczny.

Obecnie nie istnieje interfejs API Javy, który określałby, jak programowo wykonać transformację
XSLT; jednakże każdy producent procesora powinien udostępniać klasy umożliwiające
uruchomienie przekształcania z kodu Javy. Tutaj ponownie zostanie wykorzystany procesor Apa-
che Xalan; informacji o sposobie wywoływania metod transformacji w innym parserze należy za-
sięgnąć u producenta.

W przypadku procesora Apache Xalan do opisanego celu służy klasa XSLTProcessor z pakietu
org.apache.xalan.xslt. Jako parametry przyjmuje ona klasę XSLTInputSource repre-
zentującą plik XML do przetwarzania, klasę XSLTInputSource reprezentującą arkusz stylu
oraz XSLTResultTarget reprezentującą wynik transformacji. Wszystkie te klasy pomocnicze
znajdują się również w pakiecie org.apache.xalan.xslt. Klasy te tworzy się w wygodny
sposób, przekazując InputStream (do XSLTInputSource) lub OutputStream (do XSLT-
ResultTarget). Nasz dokument ma postać obiektu InputStream, arkusz stylu „zapakuje-
my” w FileInputStream, zaś interfejs serwleta pozwala nam w prosty sposób uzyskać dostęp
do obiektu ServletOutputStream poprzez metodę getOutputStream(), wywołaną na
obiekcie HttpServletResponse. Na koniec trzeba jeszcze omówić sposób uzyskania egzem-
plarza XSLTProcessor. Ponieważ do przetwarzania mogą być wykorzystane różne mechanizmy
wewnętrzne, egzemplarza tej klasy nie tworzy się bezpośrednio, ale poprzez klasę XSLTProces-
sorFactory, również znajdującą się w pakiecie org.apache.xalan.xslt. Czytelnik wie
już, jak korzystać z klas typu „factory”, a więc pozostało tylko zaimportować wymagane klasy
i dodać do serwleta wywołania metod przetwarzających:

package com.techbooks;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import javax.servlet.*;
import javax.servlet.http.*;

// Import komponentów procesora Xalan XSLT
import org.apache.xalan.xslt.XSLTInputSource;
import org.apache.xalan.xslt.XSLTProcessor;
import org.apache.xalan.xslt.XSLTProcessorFactory;
import org.apache.xalan.xslt.XSLTResultTarget;

public class ListBooksServlet extends HttpServlet {

/** Host, z którego pobierzemy listę książek */
private static final String hostname = "newInstance.com";
/** Port powyższego hosta */
private static final int portNumber = 80;
/** Plik (ścieżka URI) zawierający listę książek */
private static final String file = "/cgi/supplyBooks.pl";

1

Więcej informacji o klasie URL i operacjach wejścia-wyjścia Javy można znaleźć w książce Java I/O Eliotte Rusty

Harolda (O'Reilly & Associates).

background image

KsiegarniaTechniczna.com

339

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 339

/** Arkusz stylu, według którego przekształcimy XML */
private static final String stylesheet =

"/home/client/java/newinstance/www/javaxml/techbooks/XSL/computerBooks
.xsl";

public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

res.setContentType("text/html");

// Łączymy się w celu pobrania listy książek
URL getBooksURL = new URL("http", hostname, portNumber, file);
InputStream in = getBooksURL.openStream();

try {
XSLTProcessor processor = XSLTProcessorFactory.getProcessor();

// Przekształcamy XML za pomocą arkusza stylu
processor.process(new XSLTInputSource(in),
new XSLTInputSource(new

FileInputStream(stylesheet)),

new XSLTResultTarget(res.getOutputStream()));

} catch (Exception e) {
PrintWriter out = res.getWriter();
out.println("Błąd: " + e.getMessage());
out.close();
}
}

}

Procesor wysyła dane wyjściowe do ServletOutputStream, a więc nie trzeba nawet doda-
wać żadnych dodatkowych danych wynikowych, oczywiście poza przypadkami błędów! Teraz
można zachować serwlet jako ListBooksServlet.java i po kompilacji będzie on dostępny poprzez
mechanizm serwletów i przeglądarkę.

Jeśli Czytelnik stara się wykonywać opisywane przykłady, to przed uruchomieniem
serwleta będzie musiał przedsięwziąć pewne kroki. Po pierwsze, musi ustanowić połą-
czenie z Internetem albo dokonać zmian w przykładach, tak aby mogły być uruchamiane
lokalnie; serwlet obsługujący KsiegarniaTechniczna.com musi mieć dostęp do danych
biblioteki. Po drugie, warto wpisać kilka książek o różnej tematyce do systemu biblio-
teki poprzez interfejs HTML. W ten sposób Czytelnik będzie mógł zobaczyć, co do-
kładnie robią aplikacje i jak ze sobą współpracują. Kiedy już dane znajdują się w bibliotece,
a do samej biblioteki mamy dostęp, można uruchomić ListBooksServlet.

Uruchomiony serwlet wysyła żądanie pobrania danych z Biblioteki Publicznej NaNiby. Dane te
(lista nowych książek) są następnie przekształcane i wyświetlane na ekranie jako HTML. Odpo-
wiedź z serwleta powinna wyglądać podobnie do tej pokazanej na rysunku 13.4 — widzimy spis
nowych książek i aktualne informacje o nich (dzięki zmianom w bibliotece!); mamy także odsyłacze
pozwalające na natychmiastowy zakup wybranej książki. Klienci firmy KsiegarniaTechnicz-
na.com w prosty sposób przeglądają nowe tytuły online; pozostaje jeszcze „wypchnąć” te infor-
macje do klientów tak, aby nie musieli nawet wpisywać adresu URL. Rozwiązanie tego problemu
znajduje się w dalszej części rozdziału.

background image

340

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 340

Pobieranie a „wypychanie” informacji

Do tej pory aplikacje tworzyliśmy z założeniem, że klienci sami będą pobierali dane i zawartość.
Innymi słowy, klient musiał wpisać adres URL w przeglądarce (jak przy liście nowych książek
w witrynie KsiegarniaTechniczna.com), lub też aplikacja taka jak opisywany wyżej serwlet
musiała wysłać żądanie HTTP pobrania danych XML (jak w bibliotece). Oczywiście, nie ma tutaj
żadnego problemu — ale takie rozwiązanie nie zawsze jest najlepsze z marketingowego punktu
widzenia. Klienci pobierający dane muszą pamiętać, gdzie kupować książki, a często po jednej wi-
zycie nie powracają w dane miejsce przez dni, tygodnie i miesiące. Sporadyczne zakupy na pewno
nie przynoszą takich dochodów jak transakcje nawet mniejsze, ale za to częstsze.

Dlatego KsiegarniaTechniczna.com chce mieć możliwość wypychania (ang. push) danych do
klientów. Klient dowiaduje się o nowych pozycjach wydawniczych lub promocjach bez koniecz-
ności wykonywania jakichkolwiek działań. Wynikiem są częstsze zakupy — klient nie musi sam
pamiętać o odwiedzaniu strony. Ale w Internecie nie jest łatwo uzyskać takie wypychanie danych
— sieć globalna to nie klient uproszczony, nie da się tak po prostu wyświetlić okienka „pop-up”
z nowymi informacjami. Popularność zyskują natomiast „strony startowe” w rodzaju My Netscape
firmy Netscape czy My Yahoo firmy Yahoo. W rozmowach z Netscape przedstawiciele firmy
KsiegarniaTechniczna.com usłyszeli o technologii RSS — może to jest właśnie sposób uzyskania
zaplanowanego celu?

Rysunek 13.4. Strona HTML powstała w wyniku pobrania listy książek

background image

Pobieranie a „wypychanie” informacji

341

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 341

Rich Site Summary

Rich Site Summary (RSS) to szczególna odmiana języka XML. Posiada własną definicję DTD
i definiuje pojęcie kanału. Kanał to sposób reprezentacji danych na określony temat. Zawiera tytuł
i opis kanału, grafikę (logo) oraz szereg pozycji (ang. items) kanału. Każda pozycja to coś, co
wiąże się z kanałem, ewentualnie produkt lub usługa. Ponieważ dozwolone elementy pozycji są
raczej ogólne (tytuł, opis, odsyłacz), pozycją kanału może być niemal wszystko. Kanał RSS nie
ma dostarczać kompletnej zawartości serwisu, lecz raczej „streszczenie” informacji o firmie lub
usłudze, wyświetlane w postaci „portalowej”, ewentualnie jako pasek informacji na innej stronie
WWW. Tak naprawdę poszczególne „widżety” w serwisie Netscape Netcenter to właśnie kanały
RSS. Netscape udostępnia możliwość tworzenia nowych kanałów RSS, rejestrowanych w Net-
center. Netscape posiada również wbudowany system wyświetlania kanałów w formacie HTML,
które wtedy świetnie spisują się jako strony startowe Netcenter.

Czytelnik może w tej chwili niepokoić się, czy RSS nie jest czasem dla firmy Netscape czymś ta-
kim jak parser Microsoft XML dla firmy Microsoft — czymś zupełnie nieużytecznym w połą-
czeniu z innymi narzędziami czy produktami innych firm. Rozwiązanie to na początku faktycznie
było opracowywane pod kątem Netcenter; jednak dzięki strukturze języka XML technologia RSS
może zostać wykorzystana przez dowolną aplikację potrafiącą „czytać” pliki DTD. Coraz więcej
portali i aplikacji korzysta z RSS — przykładem może być projekt Apache Jetspeed (http://java.apa-
che.org/jetspeed
), mający na celu stworzenie systemu Enterprise Information Portal w „stylu” open
source. Jetspeed wykorzystuje dokładnie ten sam format RSS co Netscape, ale w zupełnie inny
sposób. Jest to możliwe dzięki temu, że RSS ma bardzo spójną gramatykę.

Wielu użytkowników korzysta ze stron „startowych” lub „domowych” — miejsc najczęściej od-
wiedzanych w sieci. KsiegarniaTechniczna.com postanowiła stworzyć kanał RSS przedstawiający
listę najnowszych książek i umożliwiający zainteresowanym natychmiastowy zakup określonego
tytułu. To właśnie nazwać można „wypychaniem” danych — produkty takie jak Netcenter auto-
matycznie aktualizują zawartość kanału RSS tak często, jak życzy sobie tego klient.

Tworzenie dokumentu RSS XML

Po pierwsze, konieczne jest utworzenie pliku RSS. A to jest prostsze, niż można byłoby przypusz-
czać — poza wpisaniem odwołania do właściwej DTD i trzymania się określonych w tej definicji
zasad, nie ma tutaj nic skomplikowanego. W przykładzie 13.6 pokazano propozycję pliku RSS dla
naszej księgarni.

Przykład 13.6. Przykładowy dokument RSS opisujący kanał firmy KsiegarniaTechniczna.com

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

<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
"http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">
<channel>
<title>KsiegarniaTechniczna.com Nowe Tytuły</title>
<link>http://www.newInstance.com/javaxml/techbooks/</link>
<description>
Twoje źródło książek i materiałów o tematyce komputerowej.
</description>
<language>en-us</language>

<image>

background image

342

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 342

<title>KsiegarniaTechniczna.com</title>
<url>
http://newInstance.com/javaxml/techbooks/images/techbooksLogo.gif
</url>
<link>http://newInstance.com/javaxml/techbooks</link>
<width>140</width>
<height>23</height>
<description>
Źródło książek technicznych.
</description>
</image>

<item>
<title>Java Servlet Programming</title>
<link>
http://newInstance.com/javaxml/techbooks/buy.xsp?isbn=156592391X
</link>
<description>
Doskonałe wprowadzenie do serwletów Javy i
różnych mechanizmow komunikacyjnych.
</description>
</item>

</channel>

</rss>

Element główny musi nazywać się rss; musi zostać także zdefiniowany atrybut version.
Oprócz tego, wartość tego atrybutu musi odpowiadać wersji DTD, do której się odwołujemy. W ele-
mencie głównym musi wystąpić dokładnie jeden element channel. Wewnątrz niego znajdują się
natomiast elementy opisujące dany kanał (title, link, description i language). Z ka-
nałem można również skojarzyć opcjonalny plik graficzny (oraz informacje o tym pliku). Następ-
nie może wystąpić do 15 elementów item, z których każdy opisuje jedną pozycję związaną
z kanałem. Każdy item posiada elementy title, link i description (ich znaczenia nie
trzeba chyba wyjaśniać).

Tak jak w poprzednich przykładach, również tutaj w elementach link i url nie po-

winny znaleźć się białe znaki — całość powinna mieć postać jednego wiersza. W dru-
ku nie było to możliwe, dlatego wiersz został rozdzielony.

Można także dodać opcjonalne pole tekstowe i przycisk do wysyłania informacji, czego w tym
przykładzie nie pokazano. Szczegółowy opis elementów i atrybutów znajduje się na stronie http://
my.netscape.com/publish/help/mnn20/quickstart.html
.

Tworzenie plików RSS programowo nie jest trudne; procedura podobna jest do tej, jaka została
wykorzystana przy generowaniu pliku HTML na potrzeby księgarni. Połowa pliku RSS (informa-
cje o kanale oraz o grafice) to treść statyczna; tylko elementy item są budowane dynamicznie.
Ale kiedy już programista uruchamia edytor vi i zasiada do tworzenia kolejnego arkusza XSL, na
biurku znajduje kartkę z kolejnym wymogiem: komputer, na którym znajdzie się kanał RSS, to
inny serwer niż ten używany w ostatnim przykładzie; dostępne są na nim tylko bardzo stare wersje
bibliotek Apache Xalan. Ponieważ na maszynie tej działają również pewne aplikacje wysokiej
dyspozycyjności (np. system naliczania należności), KsiegarniaTechniczna.com nie chce aktuali-
zować tych bibliotek, chyba że przy precyzyjnej kontroli efektów zmian (taki proces zajmuje
tydzień). Na samym serwerze są jednak dostępne nowsze wersje bibliotek Xerces (ponieważ w sys-

background image

Pobieranie a „wypychanie” informacji

343

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 343

temie naliczania konieczne jest przetwarzanie XML-a), a więc dostępne są również interfejsy API
Javy do obsługi XML-a.

2

Oczywiście, dałoby się tutaj wykorzystać interfejsy SAX i DOM, ale po

raz kolejny najlepszą metodą wydaje się JDOM. To za jego pomocą (przykład 13.7) dokonamy
konwersji pliku XML z Biblioteki Publicznej NaNiby na format kanału RSS.

Przykład 13.7. Serwlet Javy konwertujący listę nowych książek na dokument kanału RSS

package com.techbooks;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import javax.servlet.*;
import javax.servlet.http.*;

// JDOM
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.Builder;
import org.jdom.input.SAXBuilder;

public class GetRSSChannelServlet extends HttpServlet {

/** Z tego hosta pobieramy listę książek */
private static final String hostname = "newInstance.com";
/** Numer portu powyższego hosta */
private static final int portNumber = 80;
/** Ścieżka URI prowadząca do dokumentu */
private static final String file = "/cgi/supplyBooks.pl";

public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

res.setContentType("text/plain");
PrintWriter out = res.getWriter();

// Łączymy się i pobieramy listę książek
URL getBooksURL = new URL("http", hostname, portNumber, file);
InputStream in = getBooksURL.openStream();

try {
// Żądamy implementacji SAX i korzystamy z domyślnego parsera.
Builder builder = new SAXBuilder();

// Tworzymy dokument.
Document doc = builder.build(in);

// Wyświetlamy XML.
out.println(generateRSSContent(doc));

2

Tak, to nieco wydumany przykład, pewnie mało prawdopodobny. Ale pozwala Czytelnikowi poznać jeszcze jedną alter-

natywę co do sposobu programowego tworzenia XML-a. Jednak tak naprawdę wszystkie przykłady w tej książce (łącznie
z tymi głupiutkimi) oparte są na prawdziwych doświadczeniach związanych z prowadzeniem konsultingu w rze-
czywistych firmach!

background image

344

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 344

} catch (JDOMException e) {
out.println("Error: " + e.getMessage());
} finally {
out.close();
}
}

/**
* <p>
* Tutaj generujemy dokument RSS XML, korzystając z dostarczonego
* obiektu JDOM <code>Document</code>.
* </p.
*
* @param doc <code>Document</code> dane wejściowe.
* @return <code>String</code> - plik wyjściowy RSS.
* @throws <code>JDOMException</code> w razie wystąpienia błędów.
*/
private String generateRSSContent(Document doc) throws JDOMException {
StringBuffer rss = new StringBuffer();

rss.append("<?xml version=\"1.0\"?>\n")
.append("<!DOCTYPE rss PUBLIC ")
.append("\"-//Netscape Communications//DTD RSS 0.91//EN\" ")
.append("\"http://my.netscape.com/publish/formats/rss-

0.91.dtd\">\n")

.append("<rss version=\"0.91\">\n")
.append(" <channel>\n")
.append(" <title>Książki techniczne</title>\n")
.append("

<link>http://newInstance.com/javaxml/techbooks</link>\n")

.append(" <description>\n")
.append(" Twoje źródło książek i materiałów o tematyce

komputerowej.\n ")

.append(" </description>\n")
.append(" <language>en-us</language>\n")
.append(" <image>\n")
.append(" <title>KsiegarniaTechniczna.com</title>\n")
.append(" <url>")

.append("http://newInstance.com/javaxml/techbooks/images/techbooksLogo
.gif")

.append("</url>\n")
.append("

<link>http://newInstance.com/javaxml/techbooks</link>\n")

.append(" <width>140</width>\n")
.append(" <height>23</height>\n")
.append(" <description>\n")
.append(" Źródło książek technicznych.\n")
.append(" </description>\n")
.append(" </image>\n");

// Dodajemy element dla każdego nowego tytułu, w którym jako temat
// określono Computers.
List books = doc.getRootElement().getChildren("book");
for (Iterator i = books.iterator(); i.hasNext(); ) {
Element book = (Element)i.next();
if (book.getAttribute("subject")
.getValue().equals("Computers")) {

// Wyświetlamy pozycję.
rss.append("<item>\n")
// Dodajemy tytuł

background image

Pobieranie a „wypychanie” informacji

345

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 345

.append(" <title>")
.append(book.getChild("title").getContent())
.append("</title>\n")
// Dodajemy odsyłacz umożliwiający kupno książki
.append(" <link>")

.append("http://newInstance.com/javaxml/techbooks/buy.xsp?isbn=")

.append(book.getChild("saleDetails")
.getChild("isbn")
.getContent())
.append("</link>\n")
.append(" <description>")
// Dodajemy opis
.append(book.getChild("description").getContent())
.append("</description>\n")
.append("</item>\n");

}
}

rss.append(" </channel>\n")
.append("</rss>");

return rss.toString();
}

}

Na tym etapie nauki ani jeden fragment powyższego kodu nie powinien już Czytelnika dziwić.
Importujemy wymagane klasy JDOM i wejścia-wyjścia oraz uzyskujemy dostęp do aplikacji biblio-
teki publicznej dokładnie tak, jak w serwlecie ListBooksServlet. Wynikowy InputStream
wykorzystywany jest do stworzenia obiektu JDOM Document, za pomocą parsera domyślnego
(w JDOM 1.0 jest to Apache Xerces) oraz implementacji JDOM zbudowanej na bazie SAX-a:

// Żądamy implementacji SAX i korzystamy z domyślnego parsera
Builder builder = new SAXBuilder();

// Tworzymy dokument.
Document doc = builder.build(in);

Teraz przekazujemy Document do metody generateRSSContent(), która drukuje całą
zawartość statyczną kanału. Metoda ta pobiera elementy book z biblioteki, przetwarza je kolejno
i ignoruje te, w których jako subject określono coś innego niż „Computers”:

// Dodajemy element dla każdego nowego tytułu, w którym jako temat
// określono Computers.
List books = doc.getRootElement().getChildren("book");
for (Iterator i = books.iterator(); i.hasNext(); ) {
Element book = (Element)i.next();
if (book.getAttribute("subject")
.getValue().equals("Computers")) {

// Wyświetlamy pozycję.

}
}

Każdy element, który przejdzie pomyślnie powyższy test, dodawany jest do kanału RSS. Prawda,
że nic nadzwyczajnego? Na rysunku 13.5 przedstawiono przykładowe dane zwracane przez serw-
let, który zachowano jako plik GetRSSChannelServlet.java.

background image

346

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 346

KsiegarniaTechniczna.com udostępniła w ten sposób informacje wszystkim usługodawcom, któ-
rzy obsługują technologię RSS. Żeby jeszcze klienci mogli korzystać z takiego kanału, Ksiegar-
niaTechniczna.com zarejestruje kanał w Netscape Netcenter.

Sprawdzanie poprawności kanału RSS

Po stworzeniu kanału należy sprawdzić jego poprawność. W ten sposób nie tylko zagwarantujemy,
że dokument jest zgodny z wymogami określonymi przez definicję RSS DTD; będzie on również
zgodny z pewnymi ograniczeniami narzucanymi przez Netscape, a niemożliwymi do określenia
w definicji DTD (w przyszłości być może rozwiązaniem tego problemu będzie XML Schema).
Firma Netscape oferuje mechanizm sprawdzania poprawności kanałów online, znajdujący się pod
adresem http://my.netscape.com/publish/help/validate.tmpl. Po wpisaniu na tej stronie adresu na-
szego kanału RSS (który może mieć postać serwleta, skryptu CGI lub pliku statycznego) odpowie-
dni program sprawdzi jego poprawność. Na rysunku 13.6 przedstawiono stronę wyświetlaną po
udanym sprawdzeniu poprawności.

Teraz można już zarejestrować nasz kanał w usłudze Netcenter.

Rysunek 13.5. Kanał RSS wygenerowany przez serwlet GetRSSChannelServlet

background image

Pobieranie a „wypychanie” informacji

347

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 347

Rysunek 13.6. Potwierdzenie sprawdzania poprawności kanału RSS

Rejestracja kanału

Po sprawdzeniu poprawności opublikujemy kanał w serwisie Netcenter (lub u innego usługo-
dawcy). W tym celu wchodzimy na stronę http://my.netscape.com/publish. Należy podać nazwę
konta Netcenter, ponieważ e-mail potwierdzający zostanie wysłany na adres podany przy
zakładaniu takiego konta. Po podaniu adresu poprawnego kanału RSS, Netcenter dodaje go do
systemu kanałów i wysyła e-mail. W wiadomości takiej zawarte są instrukcje dotyczące dodania
odsyłacza do kanału RSS ze strony WWW (np. z KsiegarniaTechniczna.com, o czym za chwilę)
oraz dotyczące dodania kanału do strony startowej Netcenter.

Korzystanie z kanału

Sprawdzenie poprawności i rejestracja kanału nie przedstawiały trudności. Otrzymany e-mail
upraszcza nawet dodanie takiego kanału do strony startowej. Od tej pory nasz kanał RSS w postaci
HTML będzie można oglądać jako fragment strony startowej Netcenter. Po każdym otwarciu tej
strony startowej użytkownik zobaczy „ramkę” KsiegarniaTechniczna.com, w której znajdzie nowe
tytuły i będzie mógł je natychmiast zakupić. To na pewno zwiększy przychody ze sprzedaży online.

Aby rozreklamować kanał, do stworzonego arkusza stylu można jeszcze dodać odsyłacz, który
spowoduje automatyczne dodanie kanału do strony startowej oglądającego. Tak więc jedna ope-
racja pobrania danych może zaowocować codziennymi „wypchnięciami” oferty firmy. Oto sposób
dodania odsyłacza do arkusza:

<p align="center">
<font color="#FFFFFF"><b>
<a

href="http://newInstance.com/javaxml/techbooks/contact.html">Kontakt</
a>

</b></font>
</p>

<br>
<p align="center">
<A HREF="http://my.netscape.com/addchanneltmpl?service=net.2209">
<IMG SRC="http://my.netscape.com/publish/images/addchannel.gif"

background image

348

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 348

WIDTH="88" HEIGHT="31" BORDER="0" /></A>

</p>

</td>
<td valign="top" align="left">
<table border="0" cellpadding="5" cellspacing="5">
<tr>
<td width="450" align="left" valign="top">
<p>
<b>
Witamy w firmie <font

face="courier">KsiegarniaTechniczna.com</font>,

oferującej książki o tematyce komputerowej i technicznej.
Po lewej stronie zamieszczono najnowsze tytuły. Aby nabyć
którąś z tych wspaniałych książek, wystarczy kliknąć odsyłacz

&quot;Kup książkę!&quot; co spowoduje przeniesienie wybranej pozycji

do koszyka. Miłych zakupów!
</b>
</p>

Wprowadzenie takiego fragmentu (który otrzymujemy e-mailem z Netscape po rejestracji kanału)
spowoduje dodanie elementu graficznego, odsyłającego prosto do strony, która dodaje kanał do
strony startowej użytkownika. Sformatowana strona HTML po wprowadzeniu zmiany wygląda
tak, jak na rysunku 13.9.

Rysunek 13.9. Strona HTML z odwołaniem do kanału RSS Netscape

Przykładowy problem komunikacji typu firma-firma został rozwiązany. Punktem wyjścia była or-
ganizacja pracująca w jednym języku i bez możliwości wykorzystania XML-a (Biblioteka Publicz-
na NaNiby wraz z jej skryptami w Perlu); w wyniku działań przedstawionych w tym rozdziale
uzyskała ona możliwość komunikacji z firmą korzystającą z zupełnie innej technologii (serwlety

background image

Praktyka

349

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 349

Javy). Obie firmy nie były w żaden sposób ze sobą zsynchronizowane — żaden fragment kodu je-
dnej nie łączył się w jakikolwiek sposób z kodem drugiej. Ponieważ jako nośnik informacji został
użyty język XML, w obu firmach mogą się zmienić aplikacje, technologie, a nawet architektury,
a i tak nie wpłynie to na stworzony w rozdziale mechanizm. Następnie Czytelnik dowiedział się,
jak w wyniku takiej komunikacji można stworzyć zawartość HTML prezentowaną użytkownikom
(na zupełnie różne sposoby zależnie od aplikacji) oraz jak „wypchnąć” tę zawartość do klientów
w jeszcze jednym formacie HTML poprzez kanały RSS. Wszystko to możliwe było dzięki obe-
cnemu „za kulisami” XML-owi.

Praktyka

Niewiele więcej można powiedzieć o aplikacjach typu firma-firma. Omawiany przykład został
zaczerpnięty z życia — podobne wymagania i cele określone zostały w pewnych dużych firmach.

W kolejnych podrozdziałach Czytelnik dowie się, czym różni się to rozwiązanie skoncentrowane
wokół XML-a od technologii Electronic Data Interchange (EDI); omówione zostaną również inne
zastosowania kanałów RSS.

XML kontra EDI

Zapotrzebowanie na komunikację pomiędzy firmami jest coraz większe i to przyczyniło się do
spopularyzowania technologii Electronic Data Interchange (EDI). Drogie produkty i rozwiązania
typu „heavy-duty”, jeśli tylko na ich pudełkach widnieje napis „EDI”, od razu sprzedają się jak
świeże bułeczki. Ale te kosztowne rozwiązania, co oczywiste, nie są popularne w mniej zamoż-
nych firmach. Od kiedy pojawił się XML, nawet firmy o wysokim budżecie rezygnują z EDI na
rzecz XML-a. Wynika to nie tylko z faktu, ze XML jest rozwiązaniem wysoce standardowym, ale
również z prostoty tego języka. Przecież w jednym rozdziale został opisany sposób komunikacji
zupełnie oddzielnych systemów! Dziesięć lat temu wymagałoby to całego zespołu programistów,
a powstałe rozwiązanie i tak działałoby tylko w tych konkretnych warunkach.

Można dowieść, że XML całkowicie znosi potrzebę korzystania z EDI. Stare systemy, aplikacje włas-
ne, masywne bazy danych i produkty o podwyższonym stopniu bezpieczeństwa — one wszystkie mogą
wymieniać dane za pomocą formatu XML. Interfejsy API w rodzaju SAX-a, DOM-a, a obecnie
również JDOM-a powodują, że tworzenie pełnych rozwiązań XML jest praktyczne, a budowanie
warstw XML „na” istniejących danych w różnych formatach to kwestia tygodni i miesięcy, a nie lat.
EDI powoli zacznie znikać z rynku, jego miejsce zastąpią oferty e-biznesowe oparte na XML-u i Javie.

Kanały RSS — czy to coś trwałego?

Często pada pytanie, czy formaty XML w rodzaju RSS to rozwiązanie „trwałe”. Format ten jest
wykorzystywany w pewien konkretny sposób (np. na stronie Netscape Netcenter) — czy więc
RSS jest rozwiązaniem firmy Netscape? Tak, RSS kojarzy się z konkretną firmą, ale ponieważ
oparty jest na XML-u, może być wykorzystywany tak jak dowolny inny dokument XML. Styl
dokumentu jest całkowicie umowny, a napisanie arkusza przekształcającego RSS na WML dla
telefonów bezprzewodowych to rzecz banalna. Zresztą zostało już wspomniane, że projekt Apache
Jetspeed korzysta z RSS, a sieć O'Reilly Network (http://www.oreillynet.com) „zatrudniła” kanały
RSS w serwisach takich jak XML.com (http://www.xml.com).

Jeszcze ważniejsze jest to, że rozwiązania wykorzystujące XML z natury nie mają nic wspólnego
z rozwiązaniami „własnymi”. Dowolny dokument XML może być przekształcony tak, jak sobie

background image

350

Rozdział 13. Firma-firma

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 350

tego zażyczy autor lub programista. Nie ulega wątpliwości, że w ciągu najbliższych lat dokonana
zostanie migracja większości warstw prezentacyjnych do XML-a, bądź też konkretnej odmiany
XML-a (np. RSS). Firmy chcą budować strony o dynamicznej zawartości, ale nie mają zamiaru
zatrudniać przy tym całej armii twórców witryn.

Co dalej?

Czytelnik umie już posługiwać się XML-em „wewnątrz” kodu w Javie. Potrafi tworzyć, przetwa-
rzać, budować style, przekształcać, zawężać i sprawdzać poprawność XML-a. Wie również, jak
korzystać ze struktur publikacji, ze zdalnych wywołań procedur, jak przechowywać informacje
o konfiguracji w dokumencie XML oraz jak budować XML „w locie” z kodu Javy. To powinno
wystarczyć do zbudowania niemal dowolnej aplikacji w języku XML. W następnym rozdziale, już
ostatnim w tej książce, zostaną przedstawione schematy XML Schema. Czytelnik wie już, jak za
ich pomocą zawężać dokumenty XML; teraz dowie się, dlaczego XML Schema jest tak inno-
wacyjny, oraz jak wpływa na sposób korzystania z języka XML. Rozdział ten nie dotyczy samego
języka Java, ale omawiana w nim problematyka jest niezwykle istotna z punktu widzenia sposobu,
w jaki wykorzystywany jest język XML w aplikacjach.

background image

Co dalej?

351

C:\WINDOWS\Pulpit\Szymon\Java i XML\13-08.doc — strona 351


Wyszukiwarka

Podobne podstrony:
13 08 Piaskowanie i malowanieid 14890
KPC Wykład (13) 08 01 2013
Aneks 1 nomenklatury i def 13 08 03 19s
Podstawy psychologii - wyklad 13 [08.11.2001], ☆♥☆Coś co mnie kręci psychologia
13-08-Piaskowanie i malowanie
IS wyklad 13 08 01 09 MDW
Słowo Pana i obrazy 13.08.2011, Szkoła Modlitwy
13 08 87
Prez 13 08 00
13 08 Piaskowanie i malowanieid 14890
kitchen actions(13 08 08)
OKŁADKA ;Energy 2000 – Avatar Fluo SOBOTAParty (13 08 11) SOBOTA

więcej podobnych podstron