r04-05.doc

(479 KB) Pobierz
Szablon dla tlumaczy

W tym rozdziale:

·         Aplet

·         Serwer

·         Klient

Rozdział 4.

Odczytywanie informacji

Do utworzenia udanej aplikacji WWW niejednokrotnie potrzebna jest gruntowna znajomość środowiska, w którym będzie ona uruchamiana. Dla przykładu konieczne może okazać się zaznajomienie z serwerem, który wywołuje nasze aplety lub ze specyfikacjami klienta, który przesyła zlecenia. Bez względu na rodzaj środowiska, w którym uruchomiana jest aplikacja, jest wielce prawdopodobne, że będziemy potrzebowali informacji o zleceniach, które ona obsługuje.

Istnieje wiele metod, które umożliwiają apletom dostęp do takich informacji. Dla większości z nich każda metoda odsyła jeden, określony wynik. W porównaniu ze sposobem, w jakim zmienne środowiskowe używane są aby przekazać informacji programowi CGI, metoda apletowa ma wiele zalet, które sprawiają, że jest ona lepsza:

·         Dokładniejsza kontrola zgodności typów. Aplety otrzymują więcej pomocy ze strony kompilatora w wyłapywaniu błędów. Programy CGI używają jednej funkcji do odczytywania swoich zmiennych środowiskowych. Wiele błędów może nie zostać wykrytych aż do czasu kiedy zaczną powodować problemy wykonawcze. Teraz rzućmy okiem jak program CGI oraz aplet znajdują port, na którym działa ich serwer.

Skrypt CGI napisany w PERL-u wywołuje:

 

$port = $ENV{'SERVER_PORT'};

gdzie $port jest zmienną beztypową. Program CGI napisany w języku C wywołuje:

 

char *port = getenv ("SERVER_PORT");

gdzie port jest zmienną wskaźnikową dla ciągu znaków. Ryzyko przypadkowego błędu jest duże. Nazwa zmiennej może zostać źle przeliterowana (zdarza się to dość często) możliwe jest również, że typ danych nie będzie zgodny z odsyłanym przez zmienną środowiskową.

Aplet, z kolei, wywołuje:

 

int port = req.getServerPort()

 

Pozwala to wyeliminować wiele przypadkowych błędów, ponieważ kompilator gwarantuje

prawidłowy zapis, ponadto wszystkie typy zwracane są pozbawione nieprawidłowości.

·           Opóźnione obliczanie. W momencie uruchamiania programu CGI przez serwer wartość dla wszystkich zmiennych środowiskowych oraz każdej z osobna musi być już uprzednio przeliczona i przekazana — niezależnie od tego czy są one używane przez program CGI czy też nie są. Serwer uruchamiając aplet ma możliwość poprawienia wydajności poprzez opóźnienie podobnych kalkulacji oraz wykonywanie ich na żądanie wtedy kiedy jest to potrzebne.

·           Więcej interakcji z serwerem. W momencie kiedy program CGI rozpoczyna uruchamianie nie jest już zależny od swojego serwera. Jedyna ścieżka komunikacji, dla programu to jego standardowy port wyjściowy. Jednakże co się tyczy apletu, to może on nadal współpracować z serwerem. Tak jak to zostało omówione w poprzednim rozdziale, aplet działa albo (jeżeli to możliwe) w ramach serwera albo (jeżeli jest to konieczne) jako przyłączona procedura, poza nim. Korzystając z takiej możliwości podłączenia aplet może utworzyć zlecenia ad hoc dla informacji przeliczonych, których może dostarczyć tylko serwer. Dla przykładu serwer może wykonać dla apletu translację dowolnej ścieżki uwzględniając swoje zamienniki oraz ścieżki wirtualne.

Jeżeli przed apletami mieliśmy do czynienia z CGI, tabela 4.1 będzie pomocna w „przestawieniu się” na nowe nazewnictwo. Na tej tabeli zestawione zostały wszystkie zmienne środowiskowe CGI z odpowiadającymi im metodami apletów HTTP.

 

Tabela 4.1.

Zmienne środowiskowe CGI oraz odpowiadające im metody apletowe

 

Zmienna Środowiskowa CGI
Metoda Apletu HTTP

SERVER_NAME

req.getServerName()

SERVER_SOFTWARE

getServletContext().getServerInfo()

SERVER_PROTOCOL

req.getProtocol()

SERVER_PORT

req.getServerPort()

REQUEST_METHOD

req.getMethod()

PATH_INFO

req.getPathInfo()

PATH_TRANSLATED

req.getPathTranslated()

SCRIPT_NAME

req.getServletPath()

DOCUMENT_ROOT

getServletContext().getRealPath(„/”)

QUERY_STRING

req.getQueryString()

REMOTE_HOST

req.getRemoteHost()

REMOTE_ADDR

req.getRemoteAddr()

AUTH_TYPE

req.getAuthType()

REMOTE_USER

req.getRemoteUser()

CONTENT_TYPE

req.getContentType()

CONTENT_LENGTH

req.getContentLength()

HTTP_ACCEPT

req.getHeader(„Accept”)

HTTP_USER_AGENT

req.getHeader(„User-Agent”)

HTTP_REFERER

req.getHeader(„Referer”)

 

W pozostałej części tego rozdziału pokażemy kiedy i jak używa się tych metod oraz wielu innych, które nie mają odpowiedników CGI. Dalej będziemy również używali metod w konkretnych apletach.

Aplet

Z każdą zarejestrowaną nazwą apletu mogą być związane inne, specyficzne dla niej parametry początkowe. Aplet może mieć w każdej chwili dostęp do tych parametrów: są one określone w deskryptorze wdrożenia web.xml oraz stosowane w metodzie init() celem ustalenia wartości początkowych i domyślnych dla apletu lub dostosowania jego zachowania w określony sposób. Parametry początkowe zostały szerzej opisane w rozdziale 3 „Czas istnienia (Cykl Życia) Apletu”.

 

Pobieranie parametru początkowego apletu

Aplet używa metody getInitParameter() celem dostępu do swoich parametrów początkowych

 

public String ServletConfig.getInitParameter(String name)

 

Metoda ta odsyła odsyła: wartość początkowego parametru nazwanego lub: null (jeżeli taki nie istnieje). Odesłana wartość to zawsze pojedynczy String. Interpretacja tej wartości jest domeną apletu.

Klasa GenericServlet wdraża interfejs ServletConfig zapewniając tym samym dostęp do metody getInitParameter(). Oznacza to, że metoda może zostać wywołana w następujący sposób:

public void init() thrcws ServletException {

   String greeting = getInitParameter("pozdrowienie");

}

Aplet, któremu potrzebne jest połączenie z bazą danych może użyć swoich parametrów początkowych w celu określenia parametrów połączenia. Celem odseparowania szczegółów JDBC możemy użyć metody dostosowanej establishConnection(), tak jak zostało to pokazane na przykładzie 4.1.

 

Przykład 4.1.

Użycie parametrów początkowych w celu ustanowienia połączenia z bazą danych

 

java.sql.Connection con = null;

 

public void init() throws ServletException {

   String host = getInitParameter("komputer główny");

   int port = Integer.parseInt(getInitParameter( "port"));

   String db = getInitParameter("db");

   String user = getInitParameter("użytkownik");

   String password = getInitParameter ("hasło") ;

   String proxy = getInitParameter ("proxy") ;

 

con = establishConnection(host, port, db, user, password, proxy);

          }

Istnieje również inny, bardziej zaawansowany, standardowy model oddzielania dla apletów zaprojektowanych dla Java 2, Enterprise Edition (J2EE). Więcej na ten temat w rozdziale 12 „Aplety Przedsiębiorstw i J2EE”.

 

Pobieranie nazw parametrów początkowych apletów

Używając metody getInitParameterNames() aplet może sprawdzić wszystkie swoje parametry początkowe:

 

public Enumeration ServletConfig. getInitParameterNames()

 

Metoda ta odsyła nazwy wszystkich parametrów początkowych apletu jako Enumeration (wyliczenie) wszystkich obiektów String lub jak puste Enumeration jeżeli nie istnieją żadne parametry. Znajduje to zastosowanie przy usuwaniu błędów z programu (przy tzw. „debagowaniu”).

 

Klasa GenericServlet dodatkowo udostępnia bezpośrednio tą metodę apletom. Poniższy przykład 4.2 ukazuje aplet, który drukuje nazwę oraz wartość dla wszystkich swoich parametrów początkowych.

Przykład 4.2.

Pobieranie nazw parametrów początkowych

 

import java.io.*;

import java.util.*;

import javax.servlet.*;

 

public class InitSnoop extends GenericServlet {

 

   // Metoda init() nie jest potrzebna

 

public void service(ServletRequest req, ServletResponse res)

                           throws ServletException, IOException {

   res. setContentType (" tekst/zwykły") ;

   PrintWriter out = res.getWriter() ;

 

out.println("Parametry Początkowe:") ;

Enumeration enum = getInitParameterNames() ;

while (enum.hasMoreElements()) {

   String name = (String) enum.nextElement();

   out. println( name + ": " + getInitParameter(name));

            }

          }

        }

 

Zauważmy, że aplet ten jest bezpośrednio podrzędny do GenericServlet, dowodząc tym samym, że parametry początkowe dostępne są także dla apletów, które nie są apletami HTTP. Standardowy aplet może zostać użyty w aplikacji WWW serwera nawet w sytuacji kiedy nie realizuje zespołu funkcji. HTTP-specyficznych.

 

Pobieranie nazwy apletu

Interfejs ServletConfig również zawiera metodę, która odsyła zarejestrowaną nazwę apletu:

 

public String ServletConfig.getServletName()

 

Jeżeli aplet jest niezarejestrowany metoda odsyła nazwę klasy apletu. Metoda ta znajduje zastosowanie przy pisaniu do dzienników zdarzeń wprowadzaniu informacji o stanie kopii obiektów apletów do wspólnych zasobów takich jak baza danych czy SessionContext apletu, które wkrótce zostaną przez nas omówione.

 

Tak jak to zostało pokazane na przykładzie, poniższy kod prezentuje sposób w jaki stosuje się nazwy apletu w celu odczytania wartości z kontekstu apletu, używając nazwy jako części klucza wyszukiwania:

public void doGet (HttpServletRequest req, HttpServletResponse res)

                       throws ServletException, lOException {

   String name = getServletName() ;

   ServletContext context = getServletContext();

   Object value = context. getAttribute (name + ".stan");

}

 

Prz...

Zgłoś jeśli naruszono regulamin