Technologie szablonów dla serwletów Java

advertisement
XI Konferencja PLOUG
Kościelisko
Październik 2005
Technologie szablonów dla serwletów
Java
Dariusz Aleksandrowicz, Marek Wojciechowski
Politechnika Poznańska, Instytut Informatyki
e–mail: [email protected]
Streszczenie
Technologie szablonów dla serwletów Java stanowią alternatywę dla JSP w zakresie budowy interfejsu użytkownika w aplikacjach internetowych na platformie J2EE. Podobnie jak w przypadku JSP, motywacją dla ich powstania było umożliwienie
separacji statycznych fragmentów dokumentów HTML i kodu Java dynamicznie generującego fragmenty zmienne. Celem
niniejszego artykułu jest dokonanie przeglądu istniejących technologii szablonów oraz ocena ich możliwości i pozycji na rynku. Omówione i zilustrowane przykładem prostej aplikacji zostaną najpopularniejsze obecnie technologie szablonów: Velocity, FreeMarker i WebMacro.
Technologie szablonów dla serwletów Java
61
1. Wprowadzenie
Podstawowym zadaniem aplikacji internetowych jest generacja dokumentów HTML stanowiących interfejs użytkownika, w odpowiedzi na żądanie przesłane przez przeglądarkę WWW.
W przypadku aplikacji tworzonych w języku Java, początkowo to zadanie było realizowane przez
serwlety [Servlets]. Programista implementujący serwlet musiał zawrzeć w nim instrukcje wysyłające do strumienia wyjściowego kolejne wiersze generowanego dokumentu HTML. Kod serwletu
musiał zawierać instrukcje generujące zarówno zmienne fragmenty dokumentu HTML jak i te,
które mają charakter statyczny, tzn. nie zmieniają się między kolejnymi odwołaniami do serwletu.
Szybko zaobserwowano, że takie podejście utrudnia korzystanie z narzędzi do tworzenia dokumentów HTML i podział pracy między programistów Java i grafików – projektantów wizualnej
strony generowanych dokumentów.
Jako odpowiedź na powyższą wadę serwletów, firma Sun opracowała technologię JavaServer
Pages (JSP) [JSP]. Technologia JSP oparta została o ideę popularnej technologii ASP, zaproponowanej wcześniej przez Microsoft i cieszącej się dużą popularnością wśród twórców aplikacji internetowych. Idea polegała na zagnieżdżaniu fragmentów kodu Java w dokumentach HTML za pomocą specjalnych znaczników. Dodatkowo, zalecane było umieszczanie w miarę możliwości kodu
Java w klasach pomocniczych i odwoływanie się do nich za pomocą specjalnych konstrukcji składniowych JSP. Technologia JSP od początku swojego istnienia została zaakceptowana przez dostawców serwerów J2EE i środowisk projektanckich jako standard do tworzenia interfejsu użytkownika w aplikacjach internetowych w języku Java. Należy podkreślić, że od strony technicznej
JSP stanowi nowe wcielenie serwletów, gdyż dokumenty JSP przed pierwszym uruchomieniem są
przekształcane na serwerze do odpowiadających im serwletów. Dzięki temu JSP zachowało wiele
pozytywnych cech serwletów Java, które przyczyniły się do ich popularności.
Początkowe wersje specyfikacji JSP posiadały jednak szereg istotnych wad [Hun00], przez co
spora grupa programistów nie chciała zrezygnować z serwletów. Po pierwsze, JSP początkowo nie
pozwalały na całkowite usunięcie kodu Java z dokumentów, gdyż specyfikacja nie przewidywała
znaczników do implementacji instrukcji warunkowych czy pętli, których często wymaga logika
prezentacji. W takich przypadkach konieczne było wykorzystanie odpowiednich konstrukcji języka Java. Po drugie, konstrukcje składniowe służące do odwołania się do obiektów klas pomocniczych i ich właściwości były stosunkowo rozbudowane i mało czytelne. Do tego doszły prozaiczne, ale bardzo uciążliwe problemy z debugowaniem aplikacji JSP, gdyż sygnalizowane przez środowisko uruchomieniowe błędy odwoływały się do numerów linii wynikowego serwletu, a nie
źródłowego dokumentu JSP.
Odpowiedzią na powyższe wady JSP było powstanie technologii szablonów dla serwletów
Java. Technologie szablonów dla serwletów Java nie tylko w pełni umożliwiają, ale wręcz narzucają rozdział statycznych części generowanych dokumentów HTML i kodu Java. Koncepcja technologii szablonów polega na umieszczeniu statycznych fragmentów HTML w szablonie, w którym
zaszyte są odwołania do obiektów Java udostępnionych przez serwlet za pomocą prostej notacji,
wykorzystującej znak dolara. Języki tworzenia szablonów zostały wyposażone w konstrukcje programistyczne takie jak np. pętle, aby umożliwić implementację na poziomie szablonu złożonej
logiki prezentacji bez posiłkowania się kodem Java.
Obecnie JSP nie posiada już większości wspomnianych wyżej wad, ze względu na wsparcie dla
języka wyrażeń Expression Language (EL) i istnienie standardowej biblioteki znaczników JSTL
Core [JSTL], umożliwiających odpowiednio wygodny sposób odwoływania się do obiektów Java i
specyfikowanie pętli i warunków za pomocą znaczników JSP. W obowiązującym wzorcu projektowym model-view-controller (MVC) dla aplikacji J2EE, JSP stanowi podstawową technologię
tworzenia widoków (ewentualnie w połączeniu z komponentami JavaServer Faces [JSF]), a czysta
technologia serwletów jest wykorzystywana do implementacji kontrolera.
62
Dariusz Aleksandrowicz, Marek Wojciechowski
Technologia JSP dzięki swej ewolucji, statusowi specyfikacji firmy Sun i wsparciu komercyjnych dostawców oprogramowania, takich jak np. Oracle, skutecznie obroniła się przed technologiami szablonów skazując je na rolę technologii niszowych. Niemniej, technologie szablonów
w dalszym ciągu są rozwijane i posiadają swoich sympatyków, którym nie odpowiada składnia
JSP. Należy też podkreślić, że technologie szablonów są uwzględniane jako pełnoprawna alternatywa dla JSP w popularnych implementacjach wzorca projektowego MVC: Struts [Struts] i Spring
Framework [Spring].
Celem niniejszego artykułu jest omówienie zasady działania technologii szablonów dla serwletów Java i przedstawienie oraz porównanie trzech najpopularniejszych technologii szablonów:
Velocity [Vel], FreeMarker [FM] i WebMacro [WM].
2. Charakterystyka i zasada działania technologii szablonów
Generatory szablonów służą do generowania wszelkiego rodzaju dokumentów tekstowych
z wcześniej przygotowanych szablonów. Najczęściej stosuje się je do generowania dokumentów
HTML, ale można je stosować również do generowania dokumentów XML, RTF, WML, wiadomości e-mail, sms, kodów źródłowych programów lub plików konfiguracyjnych.
Podstawową zaletą stosowania szablonów jest możliwość pełnego odseparowania zawartości
dokumentu od warstwy znaczników opisujących jego formę. Projektant serwisu internetowego
odwołuje się do metod zdefiniowanych w kodzie języka Java. Programiści Java mogą skupić się
na tworzeniu efektywnego i elastycznego kodu. Projektanci mogą w tym czasie skupić się na stronie wizualnej serwisu. Oba zespoły mogą pracować niezależnie i równolegle. Część wizualna może powstawać nawet jeśli treść, która ją wypełni, jeszcze nie istnieje.
Kolejną cechą, jaką zauważą projektanci wykorzystujący technologię szablonów, jest czytelność wprowadzanego kodu. Nie miesza się on z kodem programu, jak ma to miejsce w innych
technologiach. Zdecydowanie ułatwia to modyfikację wyglądu serwisu oraz sprawia, że użytkownicy popełniają mniej błędów w czasie tego procesu. Łatwiejsze jest też zarządzanie serwisem,
gdyż zmiana koncepcji wizualnej strony nie wymaga angażowania programistów. Analogicznie
zmiana treści dokumentów serwisu lub sposobu dostępu do danych nie zmusza do angażowania ludzi odpowiedzialnych za wygląd strony.
Na rynku technologii generatorów szablonów dla serwletów Java istnieje trzech liczących się
producentów. Najbardziej znanym jest grupa Apache Jakarta Project (http://jakarta.apache.org/),
która w zakresie technologii szablonów tworzy i rozwija technologię Velocity
(http://jakarta.apache.org/velocity/). Kolejnym producentem, stanowiącym poważną konkurencję
dla Velocity, jest hiszpańskie stowarzyszenie Visigoth Software Society, zajmujące się technologią FreeMarker (http://freemarker.sourceforge.net/). Ostatnim autorem liczącej się technologii
szablonów jest grupa pod przewodnictwem Justina Wellsa, zajmująca się rozwojem technologii
WebMacro (http://www.webmacro.org/).
Znamienne jest, że wszystkie wspomniane wyżej technologie dostępne są na licencjach opensource. Każda jest na bieżąco rozwijana, a ich twórcy deklarują pomoc, za pośrednictwem poczty
elektronicznej, w przypadku kłopotów. Podstawowym źródłem informacji na temat technologii
szablonów są serwisy internetowe producentów. Obszerna dokumentacja dostępna w każdym
z serwisów jak również forum dyskusyjne dla użytkowników systemu pozwalają na dogłębne zapoznanie się z technologiami oraz wymianę doświadczeń pozwalającą rozwiązać ewentualne problemy w eksploatacji.
Wszystkie omówione technologie oferują podobną składnię języka tworzenia szablonów
i przyjęły podobny sposób podziału elementów konstrukcji składniowych. Zasadniczo każda
z nich ma do dyspozycji zmienne, które mogą posiadać swoje własności a nawet metody. Wynika
to z faktu, że z punktu widzenia programistów tworzących te zmienne, są one w istocie obiektami
63
Technologie szablonów dla serwletów Java
Java, a te mogą posiadać własności i metody. Większość technologii pozwala przechowywać w
zmiennych łańcuchy znaków lub wartości liczbowe całkowite.
Drugim elementem składniowym stosowanym przez wszystkie technologie są dyrektywy. Ich
zadaniem jest dostarczenie podstawowej funkcjonalności, najczęściej stosowanej przy przetwarzaniu danych, jak na przykład pętle, funkcje warunkowe czy importujące zawartość zbiorów zewnętrznych. Każda z technologii pozwala definiować własne dyrektywy zawierające dowolne
konstrukcje składniowe języka szablonu. Dyrektywy zdefiniowane przez użytkownika nazywane
są makrowyrażeniami (ang. macro).
Podstawowym zadaniem generatora szablonów jest dokonanie połączenia danych udostępnianych przez kasy Java z szablonem, określającym sposób ich wykorzystania. Szablon powinien
posiadać referencje do zmiennych oraz minimalną ilość dyrektyw tak, by projektant mógł skupić
się na kodzie HTML celem prezentacji dostarczonych mu danych, a nie przetwarzaniem ich. Jak
największa część operacji przetwarzania danych, obliczania wartości końcowych, powinna być po
stronie programisty. Projektant powinien otrzymywać gotowe do prezentacji, w pełni przetworzone dane. Dlatego istotne jest stworzenie odpowiedniego modelu danych, realizacja tego modelu
w postaci struktur implementowanych w kodzie Java oraz po odpowiednim przetworzeniu uzyskanych danych, umieszczenie ich w tych strukturach celem przekazania do szablonu. Projektantowi
pozostaje już tylko umieszczenie dostarczonych danych w odpowiednich miejscach.
W tym kontekście, zadaniem generatora jest połączenie informacji modelu danych i ich miejscami przeznaczenia opisanymi w szablonie. Sposób realizacji tego zadania ilustruje poniższy
rysunek:
Plik szablonu
<HTML>
...
Witaj ${name} !
...
</HTML>
Wyjście
Obiekt Java
import java.io.*;
void doGet(req, resp)
{...
data.name = "Alex";
...}
Generator
szablonu
<HTML>
...
Witaj Alex !
...
</HTML>
Rys. 1. Schemat łączenia danych i szablonu
Klasa Java przedstawiona na powyższym schemacie posiada obiekt data, który posiada własność name. Własność ta otrzymuje wartość w postaci łańcucha znaków „Alex”. Plik szablonu
natomiast posiada referencję do tej własności. Generator szablonu łączy te dwie struktury poprzez
wstawienie odpowiednich danych w miejsce wystąpienia referencji do tych danych. W ten sposób
powstaje dokument wyjściowy.
64
Dariusz Aleksandrowicz, Marek Wojciechowski
Generatory szablonów są dostępne w postaci bibliotek klas języka Java. W celu ich użycia nie
jest wymagana żadna szczególna procedura instalacyjny. Archiwum JAR zawierające klasy danego generatora szablonów należy umieścić na ścieżce CLASSPATH lub skopiować do odpowiedniego podkatalogu w drzewie katalogów serwera J2EE.
Generatory szablonów mogą być w zasadzie w ten sam sposób wykorzystane w różnych typach
aplikacji tworzonych w języku Java. Jednakże ze względu na fakt, że najczęściej wykorzystywane
są one w serwletach, wszystkie trzy omawiane technologie szablonów oferują wzorcową klasę
serwletu znacząco upraszczającą korzystanie z szablonów. W przypadku Velocity jest to klasa
VelocityServlet, dla FreeMarker FreeMarkerServlet, a dla WebMacro WMServlet. Programiści
aplikacji mogą tworzyć serwlety jako klasy dziedziczące z tych specjalizowanych klas serwletów
lub rozszerzyć standardową klasę HttpServlet i odwoływać się do generatora szablonów w sposób
uniwersalny.
Wykorzystanie specjalizowanych klas serwletów oferowanych przez technologie szablonów
sprowadza zadanie programisty do zdefiniowania jednej metody obsługującej żądanie. Przykładowo, w kontekście technologii Velocity i dostarczanej przez nią wzorcowej klasy serwletu VelocityServlet jest to metoda handleRequest, której jednym z parametrów jest kontekst (obiekt klasy
Context), w którym definiowane będą obiekty, do których odwołuje się szablon. Obiekty są
„umieszczane” w kontekście za pomocą metody put. Poniższy rysunek ilustruje powiązanie pomiędzy referencjami w szablonie i metodami w kodzie Java, które udostępniają obiekty odpowiadające tym referencjom, na przykładzie technologii Velocity:
Szablon dokumentu
Klasa Java
<html><head><title>Sample velocity
public Template handleRequest(Context ctx, ...
page</title>
{...
...
String p1 = "Joanna";
<h2>$tytul</h2>
String p2 = "Harold";
<i>$podtytul</i>
String tytul = "Szablon Velocity";
<table width="100%">
String podtytul = "Tworzenie listy"+
" elementów tabeli";
<tr><td
bgcolor="#eeeeee">Imiona</td></tr>
#foreach ($imie in $lista)
<tr><td bgcolor="#eeffee”
align="center">$imie</td></tr>
#end
</table></center>
</body>
</html>
...
ctx.put("tytul", tytul );
ctx.put("podtytul", podtytul );
Vector listaImion = new Vector();
personList.addElement( p1 );
...
ctx.put("lista", listaImion );
ctx.put("pl", pl ); ctx.put("log", log );
...
Template outty = null;
try{outty=getTemplate("lista_imion.vm",
"windows-1250");
} catch ( Exception e )
Rys.2. Sposób powiązania referencji i zmiennych
W powyższym przykładzie, do zawartości kontekstu szablonu, dodane są powiązania
z obiektami tutul, podtytul, oraz listaImion klasy Vector, który zawiera obiekty klasy String, zawierające imiona. Dzięki użyciu metody put klasy Context, wewnątrz szablonu można stosować
referencje $tytul, $podtytul, oraz $lista. Referencja $imie, jest referencją lokalną, z punktu widzenia szablonu, związaną ze sposobem działania dyrektywy #foreach. Gdy generator szablonu połą-
Technologie szablonów dla serwletów Java
65
czy zawartość szablonu z wartościami obiektów klas Java, wygeneruje dokument HTML, który
wyświetlony na ekranie przeglądarki internetowej będzie wyglądał tak, jak to przedstawiono na
Rys.3.
Rys.3. Efekt działania kodu przedstawionego na Rys.2
Generatory szablonów nie wymagają żadnego szczególnego środowiska uruchomieniowego.
Oczywiście dla konkretnej wersji Velocity, FreeMarker, czy WebMacro dokumentacja podaje
wymaganą wersję J2SE oraz minimalną wersję specyfikacji serwletów, którą musi wspierać wykorzystywany kontener serwletów, co jest istotne w przypadku typowego zastosowania technologii
szablonów jakim są serwlety. Ogólnie mówiąc, wszystkie rozwijane aktualnie kontenery serwletów (np. Apache Tomcat) bez problemu współpracują z generatorami szablonów.
3. Velocity
Podstawowym celem, jaki przyświecał autorom Velocity, było udostępnienie tej technologii
użytkownikom do dalszej implementacji w różnych zastosowaniach. Velocity służy, na przykład,
jako wtyczka (ang. plug-in) w edytorze programistycznym jEdit (http://www.jedit.org), pozwalająca definiować szablony standardowych funkcji dowolnych języków programowania lub często
wykorzystywanych konstrukcji składniowych. Velocity może też służyć jako rdzeń samodzielnej
aplikacji zajmującej się, na przykład, generowaniem korespondencji seryjnej, faktur dla klientów
i wielu innych systemów. Znaczącą część zastosowań Velocity stanowi jednak współpraca z technologią serwletów Java.
Język szablonów Velocity (ang. Velocity Template Language – VTL) stanowi zbiór niezbędnych konstrukcji pozwalających wykonywać typowe operacje na danych dostarczonych przez
serwlety. Autorzy systemu celowo nie poszerzają zbioru instrukcji dostępnych w ramach języka
szablonów. Zachowują tym samym przejrzystość tego języka dając jednocześnie użytkownikowi
możliwość implementacji własnych rozwiązań, lepiej dostosowanych do potrzeb jego systemu.
66
Dariusz Aleksandrowicz, Marek Wojciechowski
W skład konstrukcji składniowych Velocity wchodzą przede wszystkim dyrektywy. Pozwalają
one na konstruowanie klasycznych pętli na elementach list, warunkowe włączanie określonego
fragmentu kodu, importowanie danych ze zbiorów zewnętrznych, tworzenie makrowyrażeń powtarzających się fragmentów kodu, a nawet tworzenie własnych zmiennych, w ramach szablonu.
Podstawowym źródłem danych dla projektanta serwisu internetowego tworzącego szablon Velocity, są obiekty udostępniane przez serwlet, przygotowane przez programistę Java. Projektant
serwisu odwołuje się do nich poprzez referencje. O tym jaki typ danych przechowuje obiekt, decyduje programista Java. Od tego właśnie typu zależy jakiego rodzaju referencji do obiektu może
użyć projektant. Velocity przewiduje referencje do zmiennych, do własności obiektów oraz do
metod obiektów. Projektant ma możliwość odwoływania się do dowolnych elementów przygotowanych obiektów i wstawiania ich we właściwych miejscach szablonu, pomiędzy znacznikami
HTML i tekstem, znajdującymi się w szablonie. Istnieje również możliwość modyfikacji udostępnionych zmiennych i własności obiektów.
Metody zdefiniowane po stronie serwletu i przekazane do szablonu jako obiekty wraz z własnościami innych obiektów oraz zmiennymi, dają programistom możliwość stworzenia dowolnego
modelu danych, który przekazany do szablonu pozwala projektantom serwisu internetowego na
stworzenie dynamicznych dokumentów składających się na profesjonalną witrynę internetową.
Poniższy przykład prezentuje zastosowanie składni języka szablonów Velocity. Dla ułatwienia,
elementy składni języka Velocity zostały wyróżnione pogrubioną czcionką. Przedstawiony kod
szablonu stanowi prostą aplikację, która na podstawie parametrów wywołania serwletu oblicza
i prezentuje koszty, jakie poniesie kredytobiorca, po upływie kolejnych okresów spłaty kredytu,
wraz z odsetkami. Użytkownik podaje wysokość kredytu, oprocentowanie oraz ilość rat spłaty
kredytu. Cały proces obliczania poszczególnych wartości został przeniesiony do serwletu, który
przekazuje do szablonu jedynie wyniki obliczeń, gotowe do prezentacji w formie, którą projektant
uzna za najbardziej odpowiednią. Nie musi on skupiać się na algorytmie obliczania kosztów spłaty
kredytu. Używa jedynie referencji do wyników obliczeń.
#set ($tytul = "Wartość kredytu" )
<html><head><title>$tytul</title></head>
<body bgcolor="#FFFFFF" text="#000000">
<h2>$tytul</h2>
<b>Wysokość kredytu</b>: $kredyt zł<br>
<b>Oprocentowanie</b>:
$procent %<br>
<b>Ilość rat</b>:
$ile_rat<br>
<hr align="center" width="100%">
Miesięczna wysokość raty: <b>$raty.get(0) zł</b>,
spłacane przez <b>$ile_rat</b> miesięcy.<br><br>
<table border="1" align="left" bordercolor="#000000">
<tr align="center" valign="middle">
#foreach ( $element in $naglowek )
<th width="90">$element</th>
#end
</tr>
#set ( $jaki_kolor = 1 )
#foreach ( $element in [1..$ile_rat])
#if ( $jaki_kolor == 1)
Technologie szablonów dla serwletów Java
67
#set ( $kolor = "#66FFAA" )
#set ( $jaki_kolor = 0 )
#else
#set ( $kolor = "#AAFFFF" )
#set ( $jaki_kolor = 1)
#end
<tr align="right" valign="middle" bgcolor="$kolor">
<th align="center" width="90">$element</th>
<td width="90">$wysokosci.get($velocityCount)</td>
<td width="90">$odsetki.get($velocityCount)</td>
<td width="90">$raty.get($velocityCount)</td>
</tr>
#end
</table></BODY></HTML>
Efekt działania powyższego szablonu (w połączeniu z serwletem dokonującym obliczeń
i odwołującym się do szablonu) przedstawia poniższy rysunek.
68
Dariusz Aleksandrowicz, Marek Wojciechowski
Rys.4. Efekt działania przykładowego szablonu aplikacji prezentującej koszty kredytu
Dokumentacja technologii Velocity podzielona jest na części, przeznaczone dla różnych członków zespołów zajmujących się prowadzeniem serwisu internetowego opartego na tej technologii.
„Przewodnik użytkownika” od podstaw zapoznaje projektantów serwisów z możliwościami wykorzystania systemu, oraz całą filozofią podziału zadań między członkami zespołów. Przedstawione
są skrótowo przykładowe zastosowania podstawowych mechanizmów dostępnych w systemie
z punktu widzenia projektanta zajmującego się wizualną stroną serwisu internetowego. Osobną
część stanowi „przewodnik programisty”, przeznaczony dla programistów Java, którzy będą mieli
za zadanie tworzenie klas współpracujących z szablonami. Ponadto istnieje podręcznik języka
szablonów Velocity, który szczegółowo przedstawia składnię i przykładowe użycie wszystkich
elementów składniowych języka. Cała dokumentacja napisana jest w sposób spójny i przystępny.
Wprowadzony podział tematyczny pozwala łatwo dotrzeć do potrzebnej informacji w kontekście
swoich zadań przy wykorzystaniu technologii.
Technologie szablonów dla serwletów Java
69
4. FreeMarker
Autorzy technologii FreeMarker tworząc swój system, przyjęli odwrotną strategię niż twórcy
technologii Velocity. Dostarczają oni swoim odbiorcom wiele gotowych rozwiązań mogących
ułatwić przetwarzanie danych, typowe dla tworzenia dynamicznych dokumentów hipertekstowych.
FreeMarker posiada w zakresie swojej funkcjonalności bardzo bogatą pulę dyrektyw wraz
z wieloma opcjami. Poza podstawowymi dyrektywami są też takie, które pozwalają tworzyć konstrukcje charakterystyczne dla klasycznych języków programowania. FreeMarker pozwala definiować własne funkcje i dyrektywy, deklarować własne zmienne o różnym zakresie widzialności
oraz znacząco rozszerza ilość typów danych i obiektów dostępnych w szablonie. Jednocześnie
oferuje kilkadziesiąt funkcji wbudowanych, pozwalających zaspokoić praktycznie wszystkie potrzeby związane z przetwarzaniem przeznaczonych do prezentacji danych.
FreeMarker jasno precyzuje typy i struktury danych, jakimi będzie się posługiwał projektant
serwisu internetowego tworząc szablon. Wyróżnia zmienne skalarne, przeznaczone do przechowywania pojedynczych danych, hasze, sekwencje oraz kolekcje. Trzy ostatnie struktury stanowią
swego rodzaju kontenery zawierające inne obiekty. Różnica między nimi polega na sposobie dostępu do tych obiektów, który może być realizowany poprzez podanie łańcucha znaków skojarzonego z danym obiektem bądź poprzez podanie numeru indeksu żądanego obiektu. Każdy z tych
typów pozwala na dowolne zagnieżdżanie innych obiektów w podelementach tak, że powstaje
swego rodzaju struktura drzewiasta, charakterystyczna dla obiektowych struktur danych.
Projektant, mający dane zawarte we wspomnianych obiektach, umieszcza je w szablonie poprzez tak zwane interpolacje, czyli specjalne znaczniki zawierające odwołania do obiektów. Są to
tak naprawdę referencje, analogiczne do stosowanych w innych technologiach.
Doświadczony projektant z pewnym doświadczeniem programistycznym z dużym powodzeniem wykorzysta możliwości zawarte w technologii FreeMarker, lecz początkujący użytkownik
może poczuć się trochę zagubiony w dużej liczbie opcji oferowanych przez tę technologię. Zawsze
jednak może się ograniczyć do niezbędnego minimum funkcjonalności.
Przedstawiony poniżej kod szablonu stanowi tę samą aplikację, która została wykorzystana
wcześniej do zilustrowania składni Velocity. Tym razem aplikacja powstała przy użyciu języka
szablonów FreeMarker. Zwraca uwagę duże podobieństwo składni FreeMarker i Velocity. Gdyby
projektant serwisu, posługujący się już językiem szablonów Velocity, miał zacząć tworzyć szablony w oparciu o technologię FreeMarker, nie miałby z tym dużo problemów.
<#assign tytul = "Wartość kredytu" >
<html><head><title>${tytul}</title></head>
<body bgcolor="#FFFFFF" text="#000000">
<h2>${tytul}</h2>
<b>Wysokość kredytu</b>: ${kredyt} zł<br>
<b>Oprocentowanie</b>:
${procent} %<br>
<b>Ilość rat</b>:
${ile_rat}<br>
<hr align="center" width="100%">
Miesięczna wysokość raty: <b>${raty.get(0)} zł</b>,
spłacane przez <b>${ile_rat}</b> miesięcy.<br><br>
<table border="1" align="left" bordercolor="#000000">
<tr align="center" valign="middle">
70
Dariusz Aleksandrowicz, Marek Wojciechowski
<#list naglowek as element >
<th width="90">${element}</th>
</#list>
</tr>
<#assign jaki_kolor = 1 >
<#list 1..ile_rat as element >
<#if ${jaki_kolor} == 1 >
<#assign kolor = "#66FFAA" >
<#assign jaki_kolor = 0 >
<#else>
<#assign kolor = "#AAFFFF" >
<#assign jaki_kolor = 1 >
</#if>
<tr align="right" valign="middle" bgcolor="${kolor}">
<th align="center" width="90">${element}</th>
<td width="90">${wysokosci.get(${element_index})}</td>
<td width="90">${odsetki.get(${element_index})}</td>
<td width="90">${raty.get(${element_index})}</td>
</tr>
</#list>
</table></BODY></HTML>
Dokumentacja technologii FreeMarker również podzielona jest na części związane z podziałem
ról członków zespołu. Zawartość całego podręcznika dostępna jest z jednego menu ułożonego
hierarchicznie. Daje to wrażenie uporządkowania oraz możliwość zorientowania się w zakresie
danej tematyki już na pierwszy rzut oka. Również i tu dostępny jest podręcznik języka szablonów
z opisem wszystkich elementów składniowych i krótkimi przykładami. Na uwagę zasługuje fakt,
że w całej dokumentacji technologii FreeMarker autorzy stosują kolorowanie istotnych merytorycznie elementów tekstu, celem ich wyróżnienia. Powoduje to, że zarówno prezentacja technik
wykorzystania technologii jak i sam podręcznik języka są bardziej czytelne i zrozumiałe niż dokumentacja Velocity. Z drugiej strony autorzy systemu niekiedy zbyt ogólnie ujmują niektóre zagadnienia, zwłaszcza odnośnie konfiguracji generatora szablonu. Widać iż niektóre aspekty uważają za oczywiste i nie warte wyjaśnienia, co znacząco utrudnia uruchomienie systemu i poznanie
podstawowych mechanizmów w nim obowiązujących.
5. WebMacro
Technologia WebMacro posiada konstrukcję odpowiednią do zastosowań związanych z tworzeniem serwisów internetowych. Posiada umiarkowaną ilość dyrektyw, których funkcjonalność
dobrze nadaje się do tego celu. Składnia języka szablonów WebMacro jest bardzo podobna do
składni Velocity. Dotyczy to również nazewnictwa oraz funkcjonalności dyrektyw dostępnych
w tym języku szablonów. Wynika to z faktu, iż Velocity powstało jako alternatywa w stosunku do
WebMacro, o mniej restrykcyjnej licencji, zachowująca jego funkcjonalność. Z czasem jednak te
dwie technologie rozeszły się i w aktualnych wersjach w niektórych aspektach składnia WebMacro różni się od Velocity. Widać to wyraźnie na przykładzie sposobu oznaczania bloków kodu
szablonu, które określane są przy pomocy nawiasów klamrowych, podobnie jak w języku Java.
Technologie szablonów dla serwletów Java
71
Projektant tworzący szablon WebMacro, ma do dyspozycji zestaw dyrektyw posiadających
funkcjonalność odpowiednią do prezentacji danych w dokumentach hipertekstowych. Niektóre
dyrektywy zostały zaprojektowane specjalnie pod kątem współpracy z procedurami dynamicznie
tworzącymi tabele w formacie HTML. Inna dyrektywa pozwala kontrolować poprawność typów
obiektów przekazywanych przez serwlet do wnętrza szablonu. Jest to więc typowa technologia
przeznaczona do tworzenia serwisów internetowych, wymagająca od projektanta pewnego doświadczenia w tym zakresie.
Podobnie jak we wcześniej omawianych technologiach, język szablonów WebMacro pozwala
uzyskiwać dostęp do zmiennych, własności obiektów oraz metod obiektów, przekazanych do wnętrza szablonu przez serwlety Java. Istnieje również możliwość tworzenia własnych zmiennych
oraz modyfikacji już istniejących. Sposób użycia zmiennych i metod jak również terminologia je
opisująca jest w zasadzie tożsama ze stosowaną przy opisie systemu Velocity.
Poniższy przykład jest implementacją aplikacji prezentującej koszty kredytu w języku szablonów WebMacro. Podobieństwo składni do Velocity jest jeszcze większe, niż do FreeMarker. Wynika to z faktu, że Velocity jest następcą technologii WebMacro.
#set $tytul = "Wartość kredytu"
<html><head><title>$tytul</title></head>
<body bgcolor="#FFFFFF" text="#000000">
<h2>$tytul</h2>
<b>Wysokość kredytu</b>: $kredyt zł<br>
<b>Oprocentowanie</b>:
$procent %<br>
<b>Ilość rat</b>:
$ile_rat<br>
<hr align="center" width="100%">
Miesięczna wysokość raty: <b>$raty.get(0) zł</b>,
spłacane przez <b>$(ile_rat)</b> miesięcy.<br><br>
<table border="1" align="left" bordercolor="#000000">
<tr align="center" valign="middle">
#foreach $element in $naglowek
{
<th width="90">$element</th>
}
</tr>
#set $jaki_kolor = 1
#count $i from 1 to $ile_rat step 1
{
#if ( $jaki_kolor == 1) {
#set $kolor = "#66FFAA"
#set $jaki_kolor = 0
} #else {
#set $kolor = "#AAFFFF"
#set $jaki_kolor = 1
}
<tr align="right" valign="middle" bgcolor="$(kolor)">
72
Dariusz Aleksandrowicz, Marek Wojciechowski
<th align="center" width="90">$element</th>
<td width="90">$wysokosci.get($i)</td>
<td width="90">$odsetki.get($i)</td>
<td width="90">$raty.get($i)</td>
</tr>
}
</table></BODY></HTML>
Dokumentacja technologii WebMacro jest najgorzej zorganizowana spośród wszystkich omawianych technologii szablonów. Trudno się w niej dopatrzyć ogólnego schematu czy hierarchii.
Nie ma też wyraźnego podziału tematycznego, który pozwoliłby projektantom czy programistom
Java odnaleźć interesujące ich zagadnienia. Ponadto wiele jest miejsc zawierających merytoryczne
błędy, na przykład brak zgodności definicji elementu składni z jego zastosowaniem w poniższym
przykładzie. Niektóre przykłady zawierają opcje, które nie zostały wyjaśnione w podręczniku języka. Generalnie, dokumentacja technologii WebMacro nie zachęca do korzystania z tego systemu.
6. Porównanie technologii szablonów
Ze względu na ten sam cel, jaki mają do spełnienia, przedstawione technologie cechuje duże
podobieństwo. Jednym z założeń technologii szablonów jest dostarczenie możliwie prostego języka dla projektantów serwisów internetowych, ponieważ przyjmuje się, że mogą oni nie posiadać
doświadczenia programistycznego. Ten fakt dodatkowo ogranicza spektrum sposobów implementacji i rozwiązań stosowanych w trakcie tworzenia języka szablonów. W efekcie dostępne technologie różnią się od siebie w dużej mierze z powodu osobistych preferencji jej twórców.
Inne powody dużych podobieństw opisanych technologii są dosyć prozaiczne. Autorzy technologii Velocity na stronach serwisu internetowego ich produktu wyjaśniają przyczyny, dla których
składnia ich języka szablonów jest identyczna ze składnią systemu WebMacro. Ich zdaniem po
prostu „nie ma sensu na nowo wynajdywać koła”, a poza tym stosując tę samą składnię co konkurencja, w łatwy sposób można dostarczyć użytkownikom narzędzi do konwersji szablonów konkurencji na własny format. Zasada ta jednak działa w obie strony. Autorzy technologii FreeMarker
dostarczają narzędzi do konwersji szablonów i klas Velocity na ich format.
Pomimo oczywistych podobieństw, są jednak pewne aspekty technologii szablonów, które różnią je w znaczący sposób. Podstawową cechą systemu Velocity jest jego prostota. Jego twórcy
dbają o to, aby zbiór funkcji i dyrektyw dostępnych w języku szablonów nie powiększał się
w kolejnych wersjach systemu i zawierał tylko te, które są niezbędne. Powoduje to przejrzystość
składni języka oraz łatwość, z jaką mogą się nim posługiwać projektanci. Dyrektywy Velocity nie
posiadają całej gamy opcji. Brak jest też funkcji dedykowanych pod konkretne zastosowania, jak
ma to miejsce w technologii WebMacro. W tej ostatniej dostępne są na przykład dyrektywy wspierające tworzenie tabel w języku HTML. Velocity pozwala za to na stworzenie własnych funkcji i
dyrektyw rozszerzających funkcjonalność, lepiej dostosowanych do potrzeb jego użytkowników.
Dlatego technologia ta stanowi bazę do wielu innych zastosowań, wykraczających poza współpracę z serwletami Java.
Metody i klasy, wchodzące w skład wewnętrznej struktury technologii WebMacro, w wielu
przypadkach zadeklarowane są jako prywatne lub finalne (ang. private, final). Ma to na celu uzyskanie lepszej wydajności działania generatora szablonu. Powoduje to jednak brak możliwości
rozszerzania oraz dalszej implementacji klas wewnętrznych. Użytkownicy nie mają więc możliwości tak łatwego dostosowywania do swoich potrzeb oraz znajdywania nowych zastosowań sys-
Technologie szablonów dla serwletów Java
73
temu WebMacro, jak ma to miejsce w technologii Velocity. Być może ten fakt zdecydował o wyraźnej dominacji tej ostatniej technologii na rynku generatorów szablonów.
Autorzy technologii FreeMarker przyjęli strategię wszechstronności. Ich system posiada bogatą
gamę dyrektyw i ich opcji, funkcji oraz dostarcza znacznie więcej typów danych. Velocity oraz
WebMacro obsługują, na przykład, wartości numeryczne jedynie typu całkowitego (integer). FreeMarker natomiast przetwarza liczby zmiennoprzecinkowe, jednocześnie dając użytkownikowi
możliwość określenia ilości miejsc po przecinku. Dostępny jest również typ daty. Oba typy danych
przy wyświetlaniu na ekranie, prezentowane są w formacie zgodnym z formatem stosowanym w
kraju użytkownika. Kraj ten określany jest przez system FreeMarker na podstawie deklaracji kodowania znaków narodowych dla przetwarzanego szablonu. Co ciekawe, nawet zmienne w kodzie
szablonu mogą zawierać dowolne znaki narodowe. Ta cecha wyróżnia technologię FreeMarker
spośród pozostałych systemów.
Technologią, która jest najbardziej tolerancyjna na błędy w składni szablonu jest Velocity.
W tym systemie przyjęto zasadę, że jeśli jakaś konstrukcja nie jest zrozumiała dla systemu, to jest
ona traktowana jako tekst, który powinien się pojawić na wyjściu po przetworzeniu szablonu. Takie zachowanie może doprowadzić do przeoczenia błędów gdyż niektóre konstrukcje składniowe
mogą zginąć w gąszczu słów zwykłego tekstu. Najbardziej restrykcyjny pod względem kontroli
poprawności jest FreeMarker. Każdy błąd w jego szablonie jest sygnalizowany w oknie przeglądarki komunikatem błędu.
Technologia FreeMarker, w stosunku do pozostałych technologii, najbardziej przypomina klasyczny język programowania. Dodatkowe opcje przy wykorzystaniu pętli czy możliwości wykonywania obliczeń lub tworzenia wyrażeń nie odbiegają od tych dostępnych programistom serwletów. Definicje makrowyrażeń mogą być umieszczane w dowolnym miejscu szablonu, a nie przed
ich pierwszym wywołaniem, analogicznie do definicji funkcji w językach programowania. Velocity, dla porównania, wymaga od projektantów definiowania wszystkich makrowyrażeń przed miejscem ich wywołania.
Nieocenioną cechą systemu FreeMarker są przestrzenie nazw dla zmiennych. Pozwalają one na
przykład korzystać z bibliotek zmiennych lub makrowyrażeń bez obawy o jednakowe ich nazwy.
Programiści je tworzący nie muszą się umawiać co do nazewnictwa, gdyż każda biblioteka może
się znajdować w odrębnej przestrzeni.
Liczba wbudowanych funkcji przeznaczonych do przetwarzania łańcuchów znaków czy bezpośrednio związanych ze wspomaganiem przy tworzeniu dokumentów HTML jest w przypadku
technologii FreeMarker większa nawet w stosunku do systemu WebMacro. To bogactwo czyni
system FreeMarker najbardziej wszechstronnym, ale jednocześnie najbardziej skomplikowanym.
Do jego pełnego wykorzystania potrzebny jest doświadczony programista. Ponieważ jednak podstawowym odbiorcą technologii szablonów miał być z założenia projektant-artysta, który nie posiada żadnego doświadczenia programistycznego, można by się zastanawiać do kogo jest skierowana ta technologia. Oczywiście funkcjonalność systemu FreeMarker można uprościć poprzez
stosowanie tylko niezbędnych dyrektyw i zmiennych. Jednak wyraźnie widać, że technologia ta
jest raczej skierowana do programistów, którzy próbują swych sił na polu projektowania serwisów
internetowych lub dla tych programistów, którzy z powodu oszczędności w firmach, zmuszeni są
zajmować się zarówno programowaniem jak i projektowaniem serwisów.
74
Dariusz Aleksandrowicz, Marek Wojciechowski
7. Podsumowanie
Technologie szablonów dla serwletów Java umożliwiają i narzucają rozdział statycznych części
generowanych dokumentów HTML i kodu Java. Ich powstanie stanowiło odpowiedź na niedoskonałości wczesnych wersji technologii JSP, której geneza powstania była taka sama. Pierwotne
wersje specyfikacji JSP oferowały relatywnie złożoną składnię dostępu do obiektów Java, a do tego nie przewidywały konstrukcji typu pętle czy instrukcje warunkowe, przez co w wielu przypadkach konieczne było użycie w dokumencie fragmentów kodu w języku Java.
Aktualna wersja specyfikacji JSP nie posiada już wspomnianych wyżej wad ze względu na
wsparcie dla języka wyrażeń Expression Language i istnienie biblioteki znaczników JSTL Core.
Ponadto, od początku swojego istnienia JSP jako technologia opracowana przez firmę Sun jest
wspierana przez komercyjnych dostawców oprogramowania takich jak np. Oracle. Dlatego też,
JSP powinno być traktowane jako domyślny i naturalny wybór w zakresie prezentacji danych
w aplikacjach J2EE. Niemniej, technologie szablonów są nadal rozwijane i wykorzystywane, gdyż
koncepcja i składnia JSP nie wszystkim projektantom aplikacji J2EE odpowiada. Co więcej, technologie szablonów są uwzględniane jako pełnoprawna alternatywa dla JSP w popularnych implementacjach obowiązującego obecnie wzorca projektowego MVC (model-view-controller) Struts
i Spring Framework.
Najpopularniejsze obecnie technologie szablonów to Velocity, FreeMarker i WebMacro. Technologia Velocity jest liderem w zakresie prostoty tworzenia części wizualnej serwisu, natomiast
FreeMarker – w zakresie funkcjonalności technologii szablonów. System WebMacro stanowi
pewną wypadkową pomiędzy pierwszą i drugą technologią.
Bibliografia
[FM]
FreeMarker – The FreeMarker Project, http://freemarker.sourceforge.net/
[Hun00]
Hunter J.: The Problems with JSP, http://www.servlets.com/soapbox/problems-jsp.html,
January 25, 2000
[JSF]
JavaServer Faces Technology, java.sun.com/j2ee/javaserverfaces
[JSTL]
Java Server Pages Standard Tag Library (JSTL),
http://java.sun.com/products/jsp/jstl/index.jsp
[JSP]
JavaServer Pages Technology, http://java.sun.com/products/jsp/
[Servlets]
Java servlet technology, http://java.sun.com/products/servlet/
[Spring]
Spring Framework, http://www.springframework.org/
[Struts]
Struts, http://struts.apache.org/
[Vel]
Velocity – The Apache Jakarta Project, http://jakarta.apache.org/velocity/
[WM]
WebMacro, http://www.webmacro.org/
Download