r15-05.doc

(218 KB) Pobierz
Szablon dla tlumaczy

W niniejszym rozdziale:

·         Szkielet WebMacro

·         Instalacja WebMacro

·         Instrukcje WebMacro

·         Szablony WebMacro

·         Aplikacja „Narzędzia”

·         Filtry

Rozdział 15.

WebMacro

Szkielet programistyczny WebMacro, dostępny pod adresem http://www.webmacro.org, pochodzi z tej samej rodziny, co Tea, ale charakteryzuje się podejściem opartym w większym stopniu na serwletach. WebMacro zostało utworzone przez Justina Wellsa z firmy Semiotek jako część kontraktu na stworzenie witryny firmy. Następnie udostępnione zostało jako Open Source w celu poprawienia go i podniesienia pozycji firmy. Obecnie istnieją plany włączenia WebMacro do Apache Jakarta Project dostępnym pod adresem http://jakarta.apache.org w celu uzyskania szerszego wsparcia programistycznego. Aktualnie w projekcie Jakarta tworzony jest klon WebMacro o nazwie Velocity.

WebMacro często określa się jako mechanizm szablonów, co jest ogólną nazwą systemów wykonujących zadania zamiany tekstu wewnątrz szablonów stron WWW. Dostępne są także inne mechanizmy szablonów Open Source, najbardziej znany z nich to FreeMarker (http://freemarker.sourceforge.net). Jednak w niniejszej książce opisane zostanie WebMacro, ponieważ posiada ono największą popularność, jest wykorzystywane w dużych komercyjnych witrynach takich jak AltaVista, zostało zintegrowane z dużymi szkieletami Open Source takimi jak Turbine (http://java.apache.org/turbine) i Melati (http://www.melati.org) oraz zostało wykorzystane jako podstawa znanych projektów Open Source takich jak JetSpeed (http://java.apache.org/jetspeed). Podobnie jak Tea, WebMacro jest rozprowadzane według licencji typu Apache, tak więc może zostać bez problemu wykorzystane w połączeniu z aplikacjami komercyjnymi.

Niniejszy rozdział opisuje WebMacro 0.94, wersję próbną z października 2000. Na pewno dużo szczegółów zmieni się. Jeżeli przykładowy kod tu umieszczony nie będzie działał z ostateczną wersją, należy przeczytać dokumentacje dołączoną do WebMacro aby określić, co się zmieniło. WebMacro wymaga Servlet API w wersji 2.0 lub późniejszej i JDK 1.1.7 lub późniejszego.

Szkielet WebMacro

Szkielet WebMacro działa w następujący sposób: serwlet odbiera żądanie od klienta, serwlet wykonuje logikę konieczną do obsługi żądania (taką jak wykorzystanie klas wspierających lub elementów takich, jak EJB), po czym tworzy obiekt kontekstowy wypełniony „obiektami odpowiedzi” zawierającymi wyniki logiki, które powinny zostać wyświetlone klientowi. Następnie serwlet wybiera plik szablonu (zazwyczaj w oparciu o wyniki logiki) po czym przepycha obiekty odpowiedzi przez plik szablonu tworząc zawartość wyświetlaną klientowi.

Programista Javy tworzy serwlet i logikę w czystej Javie, a inżynier szablonów tworzy plik szablonu wyświetlający dane. Szablon składa się z zawartości HTML i XML wypełnionej prostą logiką do podstawiania i niewielkimi możliwościami skryptowymi. Składnia jest zgodna z edytorami HTML i XML, omija nawiasy kątowe, aby zapewnić, że analizatory HTML i XML nie będą popełniać omyłek. Programista przekazuje inżynierowi szablonów listę zastosowanych zmiennych, a także listę właściwości i metod tych zmiennych.

Model ten posiada pewne podobieństwa z modelem TeaServlet, z tą różnicą, że WebMacro domyślnie wykorzystuje model przepychania w większym stopniu oparty na serwletach, nie obsługuje zagnieżdżania szablonów i wykorzystuje bardziej skomplikowaną składnię skryptową. Zdaniem autorów, WebMacro posiada przewagę nad Tea przy tworzeniu wysoko funkcjonalnych stron WWW, które posiadają pewien punkt oznaczający zakończenie pracy nad nimi, Tea natomiast przoduje w tworzeniu stron, w których stale dodawana jest nowa zawartość szablonów, konieczne jest zagnieżdżanie szablonów i wymagane jest mniejsze zaangażowanie programistyczne.

Powitanie przy pomocy WebMacro

Przykład 15.1 przedstawia prosty serwlet wykorzystujący system szablonów WebMacro. Przykład 15.2 przedstawia plik szablonu witaj.wm. Wspólnie wyświetlają one aktualna datę i godzinę W następnym podrozdziale opisane zostaną miejsca, w których powinny one zostać umieszczone.

Przykład 15.1.

Prosty serwlet prowadzący szablon Witaj

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

 

import org.webmacro.*;

import org.webmacro.servlet.*;

 

public class WMWitaj extends HttpServlet {

 

  public void doGet(HttpServletRequest zad, HttpServletResponse odp)

                               throws ServletException, IOException {

    FastWriter wyj = new FastWriter(odp.getOutputStream(),

                                    odp.getCharacterEncoding());

 

    try {

      WebMacro wm = new WM(); // opcjonalnie WM("/ścieżka/do/pliku/konfiguracyjnego")

      Context k = wm.getWebContext(zad, odp);

      k.put("data", new Date());

      Template scab = wm.getTemplate("witaj.wm");

      szab.write(wyj, k);

      wyj.flush();

    }

    catch (WebMacroException w) {

      throw new ServletException(w);

    }

  }

}

Przykład 15.2.

Prosty szablon Witaj

## witaj.wm

 

#set $Response.ContentType = "text/html"

 

<HTML><HEAD><TITLE>Test WebMacro</TITLE></HEAD><BODY>

 

Witaj! <P>

 

Obecny czas to $data. <BR>

(Dla Was, kujony to $date.Time milisekund.) <P>

 

</BODY></HTML>

Na początku opisany zostanie serwlet. Jest to normalny serwlet, będący rozszerzeniem HttpServlet i wykorzystujący metodę doGet(). Na pierwszy rzut oka można jednak zauważyć, że jego logika jest inna. Pobiera on FastWriter zamiast normalnego PrintWriter. Pozwala to na specjalną optymalizację pozwalającą na uniknięcie kosztu konwersji Unicode dla zawartości statycznej. Działa on jak zwykłe urządzenie zapisujące z jednym ulepszeniem takim, że WebMacro może przepchnąć wcześniej zakodowane bajty i wywołać setAsciiHack(true) w celu przyśpieszenia wyświetlania danych Latin-1 lub US-ASCII. Należy jedynie pamiętać, by (przynajmniej obecnie) wywołać metodę flush() urządzenia zapisującego w celu wysłania zbuforowanej zawartości urządzenia do klienta.

Kod wewnątrz bloku try tworzy nowy obiekt WebMacro, który działa jako jego podstawowy zaczep do systemu WebMacro. WebMacro to interfejs, tak więc serwlet właściwie konstruuje egzemplarz konkretnej klasy WM, która implementuje interfejs WebMacro. Następnie serwlet wywołuje wm.getWebContext(zad, odp) w celu odczytania kontekstu WebContext, w którym umieszczone zostaną obiekty odpowiedzi, które zostaną przekazane szablonowi. Kontekst działa podobnie jak tablica asocjacyjna Hashtable. Posiada on metodę put(Object, Object), którą serwlet wykorzystuje do umieszczenia obiektu Date w kontekście, pod nazwą data. Obiekt ten zostanie później udostępniony szablonowi działającemu w obrębie tego kontekstu. Użytkownicy zaawansowani mogą zainteresować się faktem, że WebContext jest rozszerzeniem Context, a serwlet mógłby wywoływać kontekst nieświadomy sieci WWW — Context przy pomocy getContext(). Własność ta jest przydatna w niektórych sytuacjach, takich jak zastosowania offline lub niezwiązane z serwletami.

W celu pobrania szablonu, serwlet wywołuje wm.getTemplate("witaj.wm"). Metoda ta pobiera nazwę szablonu do odczytania, łącznie z rozszerzeniem pliku. Szablon może posiadać dowolne rozszerzenie, ale większość użytkowników wykorzystuje standardową konwencję .wm. Posiadając szablon, serwlet może wywołać jego metodę write() i przekazać jako jej parametry FastWriter do zapisu i WebContext wypełniony obiektami odpowiedzi. Wyświetlane dane powinny również zostać ujęte jako łańcuch, przy pomocy metody Template String evaluate(Context kontekst).

Jeżeli dowolna metoda spowoduje wyjątek WebMacroException, serwlet został przygotowany na wywołanie go wewnątrz ServletException. Prawie każda metoda WebMacro może wywołać WebMacroException lub pewne jego podklasy. Konstruktor WM() może wywołać InitException jeżeli, na przykład, pożądany plik konfiguracyjny nie może zostać odnaleziony. Metoda getTemplate() może wywołać NotFoundException, jeżeli niemożliwe jest odnalezienie szablonu. Natomiast metoda write() może wywołać ContextException, jeżeli pożądane dane szablonu nie znajdowały się w kontekście, a także IOException, jeżeli wystąpił problem z zapisem do klienta. Wszystkie zdefiniowane przez WebMacro wyjątki są rozszerzeniami WebMacroException, który nie jest wyjątkiem czasu wykonania, i często stosuje się obsługę tego ogólnego wyjątku na końcu metody doGet().

Stosując inne podejście, można utworzyć serwlet obsługujący WebMacro będący rozszerzeniem superklasy org.webmacro.servlet.WMServlet, jak przedstawiono w przykładzie 15.3.

Przykład 15.3.

Inne podejście do tworzenia serwletu WebMacro

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

 

import org.webmacro.*;

import org.webmacro.servlet.*;

 

public class WMSerwletWitaj extends WMServlet {

 

  public Template handle(WebContext kontekst) throws HandlerException {

    try {

      kontekst.put("data", new Date());

      return getTemplate("witaj.wm");

    }

    catch (NotFoundException w) {

      throw new HandlerException(w.getMessage());

    }

  }

}

W powyższej metodzie, serwlet jest rozszerzeniem WMServlet i implementuje pojedynczą metodę handle(). Superklasa tworzy automatycznie obiekt WebMacro i przekazuje mu jako parametr WebContext. Servlet musi wykonać jedynie swoją logikę, wypełnić WebContext odpowiednimi obiektami odpowiedzi oraz zwrócić szablon wykorzystywany do utworzenia strony (lub null, jeżeli serwlet wewnętrznie obsługuje tworzenie strony). Metody start() i stop() również mogą zostać wykorzystane przez serwlet, zamiast zwykłych metod init() i destroy(). Jeżeli potrzebne będą obiekty HttpServletRequest i HttpServletResponse, mogą one zostać odczytane z WebContext przy pomocy metod getRequest() i getResponse().

Wykorzystanie superklasy WMServlet może okazać się wygodniejsze niż samodzielna obsługa obiektów WebMacro. Jego ceną jest utrata mocy. Konieczne jest wykorzystanie samodzielnego podejścia do umieszczania na stronie dwóch niezależnych szablonów, przepuszczenia wyświetlanych danych przez filtr taki jak GZIPOutputStream, wykonania tworzenia offline, rozróżnienia między żądaniami GET i POST oraz określenia, czy serwlet musi być rozszerzeniem innej niestandardowej superklasy.

Teraz opisany zostanie szablon. Wygląda on jak zwykła strona HTML poza niewielkimi fragmentami. W głównej części strony można dostrzec obiekt Date, dodany wcześniej do kontekstu pod nazwą data, dołączony do strony przy pomocy składni $data. W następnej linii można zauważyć, że właściwość time obiektu Date (która przechowuje czas w formie licznika milisekund) została dołączona przy pomocy składni $data.Time. Jest to prosta składnia podstawienia wykorzystywana przez WebMacro — $nazwazmiennej wyświetla wartość zmiennej (po konwersji do String, jeżeli jest to konieczne), a $nazwazmiennej.Wlasciwosc wyświetla wartość właściwości. Podwłaściwości właściwości są również dostępne przy pomocy składni $nazwazmiennej.Wlasciwosc.Podwlasciwosc, a tak naprawdę można uzyskać dostęp do większej ilości danych niż podstawowe właściwości, poprzez zaawansowane działanie refleksji WebMacro, co zostanie przedstawione w dalszej części. W tym momencie należy jedynie pamiętać, że podczas odczytywania podstawowej właściwości jej nazwa musi zaczynać się od wielkiej litery.

Przyglądając się szablonowi dokładniej, można dostrzec, że na początku znajduje się komentarz zawierający nazwę pliku. Komentarze w WebMacro rozpoczynają się od ## i mają długość jednej linii. Zaraz pod komentarzem znajduje się polecenie #set, które w WebMacro nazywane jest instrukcją. Nadaje ona właściwości ContentType obiektu Response wartość "text/html", co jest równoznaczne z wywołaniem response.setContentType("text/html"). Zmienna $Response reprezentuje odpowiedź serwletu i podobnie jak $Request jest dostępna we wszystkich obiektach WebContext. WebMacro posiada kilka instrukcji służących do manipulacji zmiennymi, dołączania plików i tworzenia pętli. Zostaną one opisane szczegółowo w dalszej części niniejszego rozdziału.

Instalacja WebMacro

W celu uruchomienia serwletu WebMacro i szablonu konieczne jest wykonanie niewielkiej pracy związanej z instalacją. Po pierwsze należy pobrać dystrybucję z witryny http://www.webmacro.org i rozpakować ją. Następnie należy umieścić webmacro.jar i collections.jar w ścieżce klas serwera[1]. Następnie należy odnaleźć plik WebMacro.properties znajdujący się wewnątrz dystrybucji i skopiować go do katalogu znajdującego się w ścieżce klas serwera. Proszę zauważyć, że ponieważ klasy w webmacro.jar wykorzystują swój własny mechanizm ładowania klas w celu odnalezienia pliku, plik ten musi znajdować się w ścieżce klas mechanizmu ładującego webmacro.jar. W celu zapewnienia tej własności, należy umieścić oba te pliki w systemowej ścieżce klas, gdzie mogą zostać odnalezione przez podstawowy mechanizm ładowania klas, lub umieścić oba w katalogu WEB-INF, gdzie zostaną odnalezione przez mechanizm aplikacji WWW. (webmacro.jar należy umieścić w katalogu WEB-INF/lib, a WebMacro.properties w katalogu WEB-INF/classes.)

Domyślny plik WebMacro.properties zawarty w dystrybucji zawiera długą listę opcji konfiguracyjnych, których pierwsza część jest przedstawiona w przykładzie 15.4. Większość aspektów tej klasy jest dobrze udokumentowana w samym pliku. Wszystko, co należy teraz skonfigurować, to parametr TemplatePath, określający katalog lub katalogi, w których przechowywane są szablony.

Przykład 15.4.

Standardowy plik WebMacro.properties

# UWAGA DLA UŻYTKOWNIKÓW NT

#                                                                 

# Proszę pamiętać, że znak \ to znak ucieczkowy w plikach właściwości Javy

# Należy je zdublować (\\) lub wykorzystać w pliku znak Uniksowy (/)

# Oba powinny działać. Również podczas określania TemplatePath, proszę pamiętać

# o stosowaniu znaku oddzielającego NT (;), a nie Uniksa (:)

 

###########################################################

#

# KONFIGURACJA PODSTAWOWA:

#

 

# Należy co najmniej określić TemplatePath! Jest to lista katalogów, która będzie

# przeglądana w poszukiwaniu szablonów, jeżeli podana zostanie ścieżka względna

# Jest to lista oddzielana przez : (UNIX) lub ; (NT).

 

TemplatePath = /tomcat/webapps/webmacro/WEB-INF/szablony;/local/webmacro/szablony

 

 

# WebMacro kompiluje i przechowuje szablony w celu osiągnięcia maksymalnej wydajności.

# Podczas programowania poleca się wyłączenie tego przez ustawienie wartości na 0

# tak, że zmiany w szablonach natychmiastowo odbijają się w witrynie.

# W systemach produkcyjnych jest to ilość milisekund wolnego czasu, przez który szablon

# szablon umieszczony w pamięci podręcznej będzie przechowywany np. 600000 to 10 minut.

 

TemplateExpireTime = 0

# TemplateExpireTime == 600000

 

 

# LogLevel może wynosić: ALL, DEBUG, EXCEPTION, ERROR, WARNING, INFO, or NONE

# w porządku od największej do najmniejszej ilości wyświetlanych informacji.

 

LogLevel = EXCEPTION

 

 

# LogTraceExceptions powoduje umieszczanie stosów wyjątków w pliku dziennika,

# co powoduje zwiększenie długości wyjątków i ich wskazywanie na konkretną linię lub

# metodę, która powoduje błąd.

 

LogTraceExceptions = TRUE

 

 

# Usunięcie komentarza powoduje zapisywanie w pliku dziennika, nie w stderr.

# Jeżeli standardowy błąd już zapisuje w przydatnym dzienniku, nie trzeba tego robić,

...

Zgłoś jeśli naruszono regulamin