r02-05.doc

(280 KB) Pobierz
Szablon dla tlumaczy

 

W tym rozdziale:

·         Podstawy HTTP

·         Interfejs API (Servlet API)

·         Tworzenie strony

·         Aplikacje WWW

·         Przejdźmy dalej

 

Rozdział 2.

Aplety Http — wprowadzenie

Ten rozdział to krótki samouczek pisania i uruchamiania prostych apletów HTTP.

Opisane tutaj zostanie jak wdrożyć aplet do standardowej aplikacji WWW i jak skonfigurować jego zachowanie przy użyciu XML-owego deskryptora rozmieszczenia.

W przeciwieństwie do pierwszej edycji niniejszej książki, ten rozdział obecnej nie opisuje opartych na apletach plików dołączanych serwera (SSI) lub wiązania łańcuchowego oraz filtrowania apletu. Mimo tego, iż techniki te były bardzo przydatne oraz zostały umieszczone w serwerze WWW (Java Web Server), nie zostały zatwierdzone w specyfikacji apletu, (która ukazała się po pierwszej edycji niniejszej pozycji). SSI zostały zastąpione przez nowe techniki tworzenia plików dołączanych programu. Wiązanie łańcuchowe apletu zostało uznane za zbyt nieczytelne dla oficjalnego zatwierdzenia, mimo tego jest wielce prawdopodobne, że sama jego idea zostanie wykorzystana w Interfejsie API 2.3 (Servlet API 2.3) jako część oficjalnego mechanizmu ogólnego zastosowania przed i po — filtrującego.

 

Zwróćmy uwagę, iż możliwe jest ściągnięcie kodów dla każdego z przykładów zamieszczonych w tym oraz innych rozdziałach tej książki, zarówno w formie źródłowej jak i skompilowanej (jak zostało to opisane w przedmowie). Jednakże, co się tyczy tego rozdziału, wydaje się, iż rzeczą najbardziej pomocną w nauce będzie zapisanie przykładów ręcznie (za pomocą klawiatury). Lektura tego rozdziału może prowadzić do wniosku, iż niektóre zagadnienia zostały potraktowane zbyt ogólnie. Aplety to narzędzia dające wiele możliwości i czasem bywają skomplikowane, dlatego też rozdział ten ma na celu wprowadzenie w ogólne zasady ich działania i zorientowania się w temacie. Czytelnik po lekturze niniejszej książki będzie w stanie samodzielnie tworzyć najrozmaitsze aplety.

Podstawy HTTP

Zanim przejdziemy do omawiania prostych apletów HTTP, musimy sprawdzić znajomość podstaw działania protokołu HTTP. Będąc doświadczonym w programowaniu w CGI (lub mając doświadczenie w tworzeniu stron WWW na serwerach) można z powodzeniem pominąć czytanie tego podrozdziału. W takim przypadku korzystnym wydaje się zatrzymanie się na istotnych zagadnieniach metod GET i POST. Jednakże będąc osobą stawiającą pierwsze kroki w tworzeniu stron WWW na serwerach, należy przeczytać wspomniany materiał uważnie, ponieważ zrozumienie dalszej części książki wymaga znajomości protokołu HTTP. Protokół HTTP został szczegółowo omówiony w „Pocket Reference” Clintona Wong’a (wydawnictwo O’Reilly)

Do red.prow.: Może coś naszego?

.

Zlecenia, odpowiedzi, nagłówki

HTTP jest prostym, międzynarodowym protokołem. Klient, np. przeglądarka WWW składa zlecenie, serwer WWW odpowiada i dokonywana jest tzw. „obsługa zlecenia”. Kiedy klient składa zlecenie, pierwszą rzeczą którą wykonuje, jest komenda HTTP zwana metodą, za pomocą której serwer orientuje się jaki rodzaj zlecenia jest składany. Pierwszy wiersz zlecenia określa adres dokumentu (URL) oraz używaną wersję protokółu HTTP. Oto przykład:

GET/intro.html Http/1.0

 

W tym zleceniu chodzi o uzyskanie dokumentu o nazwie intro.html za pomocą wersji 1.0 HTTP. Po przesłaniu zlecenia klient może przesłać informacje nagłówkową w celu dostarczenia serwerowi dodatkowych informacji o zleceniu, takich jak: jakie oprogramowanie jest używane przez klienta oraz jaka forma informacji potrzebna jest klientowi do jej zrozumienia. Takie informacje nie odnoszą się bezpośrednio do tego, co było przedmiotem zlecenia, jednakże mogą być wykorzystane przez serwer w tworzeniu odpowiedzi. Oto dwa przykłady nagłówków zleceń:

 

User-Agent : Mozilla/4.0 (compatabile; MSIE 4.0; Windows 95)

   Accept : image/gif, image/jpeg, text/*, */*

 

Nagłówek User-Agent dostarcza informacji o oprogramowaniu klienta, podczas gdy nagłówek Accept określa rodzaj nośnika (MIME) najkorzystniejszy dla klienta (nagłówki zleceń zostaną omówione szerzej przy omawianiu apletów, w rozdziale 4 „Odczytywanie informacji”). Celem zaznaczenia końca sekcji nagłówkowej, po przesłaniu nagłówków, klient przesyła nie zapisany wiersz. Jeżeli wymaga tego używana metoda, klient może również przesłać inne dodatkowe dane, tak jak w przypadku metody POST, która zostanie zaraz omówiona. Jeżeli zlecenie nie zawiera żadnych danych, to kończy się nie zapisanym wierszem. Po przesłaniu przez klienta zlecenia, serwer przetwarza je i przesyła odpowiedź. Pierwszy wiersz odpowiedzi zawiera wiersz statusu oraz jego opis. Oto przykład:

HTTP/1.0 200 OK.

Powyższy wiersz statusu zawiera kod statusu 200, co oznacza że zlecenie zostało wykonane, stąd opis OK. Kolejny często spotykany kod to 404 z opisem Not Found (nie znaleziono), jak łatwo się domyśleć opis ten oznacza, że dokument nie został odnaleziony. W rozdziale 5 „Przesyłanie informacji HTML” zostały omówione najczęściej spotykane kody statusu oraz w jaki sposób można je wykorzystać w apletach. Dodatek D „Kody statusu HTTP

Tytuł Dodatku D

” zawiera kompletną listę kodów statusu HTTP. Po przesłaniu wiersza statusu serwer przesyła nagłówki odpowiedzi, które są informacją dla klienta taką jak np.: jakiego oprogramowania używa serwer oraz nośnika informacji użytego do zapisania odpowiedzi serwera. Oto przykład:

 

Date: Saturday, 23-May-00 03:25:12 GMT

Server: Tomcat Web Server/3.2

MIME-version:1.0

Content-type: text/html

Content-length: 1029

Last-modified: Thursday, 7-May-00 12:15:35 GMT

Nagłówek Server dostarcza informacji o oprogramowaniu serwera, nagłówek Content-type określa rodzaj rozszerzenia MIME odnośnie danych zawartych w odpowiedzi (nagłówki odpowiedzi zostaną omówione szerzej w rozdziale 5). Po nagłówkach serwer przesyła „czysty wiersz” celem zakończenia sekcji nagłówkowej. Jeżeli zlecenie zostało wykonane, żądane dane są następnie przesyłane jako część odpowiedzi. W przeciwnym wypadku odpowiedź może zawierać informację tekstową dla osoby obsługującej przeglądarkę, która będzie wyjaśniała dlaczego serwer nie mógł wykonać zlecenia.

Metody GET i POST

Klient łącząc się z serwerem może złożyć zlecenie w kilku różnych formach, zwanych metodami. Najczęściej używane metody to GET i POST. Metoda GET służy do uzyskiwania informacji (dokumentów, wykresów, informacji bez danych), podczas, gdy metoda POST została zaprojektowana z myślą o wysyłaniu informacji (numerów kart kredytowych, danych statystycznych lub informacji baz danych). Wykorzystując analogię elektronicznego biuletynu informacyjnego, GET służy do czytania a POST do zamieszczania w nim tekstu. GET to metoda używana do wprowadzania URL-u bezpośrednio do przeglądarki lub podczas klikania na hiperlink; jednakże zarówno metoda GET jak i POST mogą być używane do dostarczania formularzy HTML.

Mimo, iż metoda GET została zaprojektowana w celu odczytywania informacji, może zawierać jako część zlecenia informacje własne, które dokładniej precyzują to zlecenie. Może to być np. układ współrzędnych x,y dla wykresów. Takie informacje są przesyłane jako ciąg znaków dołączonych do URL-u w formie znanej ciągiem zapytań. Ten sposób zamieszczania dodatkowych informacji w URL-u umożliwia przesłanie strony e-mailem bądź utworzenie z niej zakładki. Ponieważ zlecenia GET nie są przeznaczone do przesyłania dużych partii informacji, niektóre serwery ograniczają długość URL-ów i ciągów zapytań do około 240 znaków.

W metodzie POST używana jest odmienna technika przesyłania informacji do serwera, ponieważ niekiedy metody tej używa się do przesyłania większych partii informacji. Zlecenie złożone za pomocą metody POST przesyła bezpośrednio wszystkie informacje (nie ograniczone co do długości) w nim zawarte za pomocą połączenia gniazdowego jako część swego zlecenia HTTP. Klient nie jest informowany o tej zamianie, URL nie ulega w ogóle zmianie. W efekcie zlecenia POST nie mogą być ani zapisane jako zakładki, ani wysłane e-mailem, ani też w niektórych przypadkach nie mogą być w ogóle powtórnie załadowane. Powód jest prosty — sytuacja taka wynika z odpowiedniego zaprojektowania — informacja jak np. numer naszej karty kredytowej, powinna być przesyłana do serwera tylko raz. Stosując metodę POST uzyskujemy dodatkowo pewien stopień zabezpieczenia przy przesyłaniu poufnych informacji, ponieważ dziennik zdarzeń, który zapisuje wszystkie zgłoszenia URL-ów, nie rejestruje danych metody POST.

W praktyce użycie metod GET i POST odbiega od celu, dla którego zostały zaprojektowane. Powszechną praktyką przy składaniu długich parametryzowanych zleceń na informacje jest użycie POST zamiast GET w celu uniknięcia problemów związanych z nadmiernie długimi URL-ami. Metoda GET jest również często wykorzystywana do ładowania informacji przez proste formularze ponieważ, no cóż, po prostu da się to w ten sposób zrobić. Powyższe problemy nie są jednak aż tak dramatyczne, wystarczy tylko pamiętać, iż zlecenia GET (z powodu tego, iż mogą być w prosty sposób zamieniane na zakładki) mogą wywołać zmianę na serwerze, za którą odpowiedzialny będzie klient. Chodzi o to, że zlecenia GET nie powinny być używane do składania zleceń, uaktualniania baz danych oraz do innych działań umożliwiających identyfikację klienta (w przypadku wystąpienia zmian na serwerze).

Pozostałe metody Http

Poza GET i POST istnieje jeszcze wiele, rzadziej używanych metod HTTP, takich jak na przykład metoda HEAD. Metoda ta jest używana przez klienta tylko do uzyskiwania nagłówków odpowiedzi, w celu określenia rozmiaru dokumentu, czasu modyfikacji lub ogólnej dostępności. Inne metody to PUT — do zamieszczania dokumentów bezpośrednio na serwerze, DELETE — wykorzystywana do ich usuwania stamtąd. Dwie ostatnie metody nie współpracują ze wszystkimi serwerami z powodu skomplikowanych procedur. Metoda TRACE jest powszechnie używana do usuwania błędów — umożliwia przesłanie klientowi dokładnej treści jego zlecenia. Metoda OPTIONS może być użyta do zapytania serwera, z którymi metodami współpracuje lub jak dotrzeć do poszczególnych jego zasobów.

Interfejs API (Servlet API)

Po zapoznaniu się z podstawami HTTP, możemy przejść do omówienia interfejsów API, których z kolei używa się do tworzenia apletów HTTP, lub innych rodzajów apletów odpowiednich dla tej materii. Aplety używają klas i interfejsów z dwóch pakietów: javax.servlet i javax.servlet.http. Pakiet javax.servlet zawiera klasy i współpracuje ze standardowymi protokołowo–niezależnymi apletami. Klasy te są rozszerzane przez klasy w pakiecie java.servlet.http w celu dodania funkcjonalności specyficznej dla HTTP. Pakiet najwyższej klasy nazywa się javax zamiast zwykłego java, aby zasygnalizować, iż Interfejs API jest pakietem dodatkowym (uprzednio zwanym Standardowym Rozszerzeniem). Każdy aplet musi wdrożyć interfejs javax.servlet. Większość apletów wdraża ten interfejs przez rozszerzenie jednej z dwóch specjalnych klas: javax.servlet.GenericServlet lub javax.servlet.http.HttpServlet. Aplet niezależny protokołowo powinien być podrzędny do GenericServlet, a aplet HTTP powinien być podrzędny w stosunku do HTTPservlet, który sam jest podklasą GenericServlet z dodana funkcjonalnością HTTP.

W przeciwieństwie do zwykłego programu Java, i dokładnie tak jak zwykły aplet, aplet wykonywany na serwerze nie zawiera metody main(). Zamiast tego pewne metody apletów wywoływane są przez serwer w procesie obsługi zleceń. Za każdym razem, kiedy serwer wysyła zlecenie do apletu, wywołuje jego metodę service().

Standardowy aplet w celu poprawnej obsługi zlecenia powinien zignorować swoją metodę service(). Metoda service() akceptuje dwa parametry: obiekt zlecenia i obiekt odpowiedzi. Obiekt zlecenia informuje aplet o zleceniu, a obiekt odpowiedzi używany jest do wysyłania odpowiedzi. Rysunek 2.1. ukazuje jak standardowy aplet obsługujący zlecenie.

Rysunek 2.1. Standardowy aplet obsługujący zlecenie

 

Aplet HTTP zwykle nie ignoruje metody service(), tylko metodę doGet() (do obsługi zleceń GET) i metodę doPost() (do obsługi zleceń POST). Aplet HTTP może zignorować jedną z powyższych metod lub obie, w zależności od tego, jaki jest typ zlecenia, które ma obsłużyć. Metoda service() HttpServlet obsługuje instalację oraz transfer do wszystkich metod doXXX(), dlatego właśnie zwykle nie powinna być ignorowana. Na rysunku 2.2 został ukazany sposób, w jaki aplet HTTP obsługuje zlecenia metod GET i POST.

Rysunek 2.2. Aplet HTTP obsługujący zlecenia GET i POST

Aplet HTTP może zignorować odpowiednio metody doPut() i doDelete() celem obsłużenia zleceń PUT i DELETE. Jednakże aplety HTTP generalnie nie modyfikują metod doTrace() czy doOptions(). Dla nich prawie zawsze wystarczające są implementacje domyślne.

Pozostałe klasy w pakietach javax.servlet i javax.servlet.http to w większości klasy wspomagające. Na przykład klasy ServletRequest i ServletResponse w javax.servlet umożliwiają dostęp do zleceń i odpowiedzi standardowych serwerów, natomiast klasy HttpServletRequest i HttpServletResponse w javax.servlet.http umożliwiają dostęp do zleceń i odpowiedzi HTTP. Pakiet javax.servlet.http zawiera również klasę HttpSession, która oferuje wbudowaną funkcjonalność śledzenia sesji oraz klasę Cookie, która pozwala na szybkie instalowanie i przetwarzanie cookies.

Tworzenie strony

Najbardziej podstawowy typ apletu HTTP tworzy pełną stronę HTML. Taki aplet ma zwykle dostęp do takich samych informacji, co przesyłane do skryptu CGI oraz do pewnej partii innych. Aplet, który tworzy strony HTML może zostać użyty do wykonywania wszystkich zadań, tych które obecnie są wykonywane przy pomocy CGI, jak np. przetwarzanie formularzy HTML, tworzenie listy z bazy danych, przyjmowanie zamówień, sprawdzanie zamówień, sprawdzanie identyfikacji, itd.

Pisanie „Hello World”

Przykład 2.1 ukazuje aplet HTTP tworzący kompletną stronę HTML. Dla uproszczenia sprawy aplet ten ,za każdym połączeniem się z nim za pomocą przeglądarki WWW, wyświetla napis „Hello World”.*

Przykład 2.1. Aplet, który wyświetla „Hello World”

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

 

public class HellWorld extends HttpServlet   {

 

  public void doGet (HttpServletRequest  req, HttpServletResponse res)

                                throws ServletException, IOException {

 

     res.setContentType ("text/html");

     PrintWriter  out  = res.getWriter ( );

   

     out.println("<HTML>");

     out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>");

     out.println ("<BODY>") ;

     out.println (<BIG>Hello World</BIG>");

     out.println ("</BODY><HTML>");

  }

}

Powyższy aplet rozszerza klasę HttpServlet oraz ignoruje odziedziczoną z niej metodę doGet(). Kiedy serwer WWW otrzymuje zlecenie GET z tego apletu, każdorazowo wywołuje metodę doGet(), przekazując mu obiekty HttpServletRequest oraz HttpServletResponse. Obiekt HttpServletRequest reprezentuje zlecenie klienta. Obiekt ten daje apletowi dostęp do informacji o kliencie, parametrach zlecenia, nagłówkach HTTP przekazywanych razem ze zleceniem oraz inne. W rozdziale 4. omówione zostały wszystkie możliwości obiektu zlecenia. Dla tego przykładu możemy jednak je pominąć jako, ze niezależnie od typu zlecenia aplet ten wyświetla „Hello World”.

Obiekt HttpServletResponse reprezentuje odpowiedź apletu. Aplet może wykorzystać ten obiekt do dostarczenia danych klientowi. Mogą to być dane różnego typu, typ ten jednak powinien być określony jako część odpowiedzi. Aplet może również użyć tego obiektu do ustalenia nagłówków odpowiedzi HTTP. W rozdziałach 5. i 6 „Przesyłanie treści multimedialnej” zostało omówione wszystko co może zrobić aplet jako część odpowiedzi.

Nasz aplet ustala najpierw za pomocą metody setContentType() typ zawartości swojej odpowiedzi do text/html, standardowego typu zawartości MIME dla stron HTML. Następnie używa metody getWriter() w celu odczytania PrintWriter, międzynarodowego odpowiednika PrintStream. PrintWriter przekształca kod UNICODE Javy na kodowanie specyficzne lokalnie. Dla kodowania lokalnego — angielskiego zachowuje się tak jak PrintStream. Aplet używa wreszcie PrintWriter do wysłania swojego HelloWorld HTML do klienta.

Uruchamianie „Hello World”

Do tworzenia apletów potrzebne są dwie rzeczy: pliki klasy interfejsu API, które używane są w tłumaczeniu programu źródłowego na język wynikowy oraz pojemnik apletu np. serwer WWW, który używany jest z kolei przy uruchamianiu apletów. Wszystkie popularne pojemniki apletów oferują pliki klasy Interfejsu API, więc można spełnić oba warunki (potrzebne do tworzenia apletów) za jednym ładowaniem.

Istnieją dziesiątki parametrów dostępnych pojemników apletów dla wdrażania apletów, kilkanaście z nich zostało zamieszczonych w rozdziale 1 „Wprowadzenie”. Dokonując wyboru serwera należy pamiętać, że musi on współpracować z wersją 2.2 Interfejsu API (Servlet API 2.2) lub późniejszą. Wersja 2.2 była pierwszą wersją Interfejsu API, która zapewniała dostęp do aplikacji WWW, jak zostało to omówione w tym rozdziale. Aktualna lista pojemników apletów oraz tego do jakiego poziomu API zapewniają one dostęp i jest dostępna pod adresem: http://www.servlets.com.

Tak więc zapytajmy, co należy zrobić z naszym kodem, aby zadziałał w serwerze WWW? — to zależy od rodzaju serwera. W przykładach zaprezentowanych w tej książce występuje serwer „Apache Tomcat 3.2”, serwer implementacji odniesienia API, napisany całkowicie w Javie, dostępny pod adresem: http://jakarta.apache.org. Serwer „Tomcat” zawiera mnóstwo dokumentacji, w której jest wyjaśnione jego zastosowanie. W niniejszej książce dlatego właśnie omówione zostaną tylko ogólne zasady dotyczące pracy z serwerem. Poniższe omówienia powinny być także zgodne z innymi serwerami (niż „Tomcat”) jednakże nie można tego zagwarantować.

Jeżeli używamy serwera „Apache Tomcat”, to powinniśmy umieścić kod źródłowy dla apletu w katalogu server_root/webapps/ROOT/WEB-INF/classes (gdzie server_root jest katalogiem , w którym zainstalowaliśmy nasz serwer), jest to standardowa lokalizacja plików klasy apletu. Powód, dla którego aplety występują w tym katalogu zostanie omówiony później w tym rozdziale.

Kiedy już mamy właściwie umiejscowiony kod źródłowy HelloWorld, musimy go skompilować. To zadanie możemy wykonać przy pomocy standardowego kompilatora javac (lub naszego ulubionego środowiska graficznego Javy). Należy się tylko upewnić, że mamy pakiety javax.servlet i javax.servlet.http w naszej ścieżce klasy. Pracując z serwerem „Tomcat”, wystarczy tylko zamieścić server_root/lib/servlet.jar (lub przyszły odpowiednik) gdzieś w naszej ścieżce klasy. Nazwa pliku oraz lokalizacja zależą od serwera, więc w razie problemów trzeba zajrzeć do dokumentacji serwera, z którym mamy do czynienia. Jeżeli wyświetlony zostanie komunikat informujący o błędzie taki jak np. Package javax.server not found in import...

Zgłoś jeśli naruszono regulamin