Nadszedł czas, aby poznać młodszego brata Tapestry, frameworka dla Javy. Wicket, bo o nim mowa, również wywodzi się spod skrzydeł fundacji Apache. Wicket proponuje podobne podejście do budowania serwisów internetowych do tego znanego z Tapestry, lecz… całe zadanie czyni jeszcze prostszym!
Co więcej, o ile Tapestry wciąż pozostaje
frameworkiem mało popularnym, o tyle
Wicket zdobywa coraz większą rzeszę
zwolenników. Czas na to, abyś i ty mógł się z nim
zapoznać.
Zanim rozpoczniesz pracę z nowym frameworkiem,
zadbaj o przygotowanie odpowiedniego
środowiska. Potrzebne będą:
- skonfigurowane środowisko JDK – zakładam, że
już dawno je posiadasz, - Maven – mimo że da się bez niego obyć, znacznie
ułatwia pracę nad projektem, więc będziemy
z tych dobrodziejstw korzystali.
Do naszych testów nie będzie potrzebny kontener
servletów, taki jak np. Tomcat. A to za sprawą
użycia archetypu do mavena, który pozwala na
uruchomienie projektu za pomocą wbudowanego
kontenera Jetty.
Jeśli masz zainstalowanego Mavena, nie
musisz nawet pamiętać o pobraniu frameworka
z jego strony domowej (http://wicket.apache.org).
Możemy zaczynać.
Zaczynamy
Pierwszy przykład to kultowe już Witaj Świecie.
Utwórzmy więc nowy projekt, korzystając z Mavena.
Na stronie http://wicket.apache.org/quickstart.
html znajdziesz formularz ułatwiający generowanie
polecenia tworzącego odpowiednią strukturę
katalogów. Polecenie, którego użyjemy do zbudowania
naszego programu Hello World, wygląda
następująco:
mvn archetype:create
-DarchetypeGroupId=org.apache.wicket
-DarchetypeArtifactId=wicket-archetypequickstart
-DarchetypeVersion=1.3.1
-DgroupId=pl.staniszczak
-DartifactId=HelloWorld
W linii poleceń przejdź do katalogu, w
którym chcesz utworzyć nowy projekt, wpisz
powyższe polecenie i uruchom je. Po zakończeniu
działania (rysunek 1) utworzony zostanie
katalog projektu wraz z całym drzewem
niezbędnych katalogów i plików.
Pamiętaj że pierwsze uruchomienie powyższego polecenia
może wykonywać się stosunkowo długo,
gdyż powoduje pobranie dużej ilości plików
z internetu. Na rysunku 2 pokazano drzewo
katalogów naszego projektu.
W poszczególnych katalogach projektu będziemy
umieszczali:
- /src/main/java/pl/staniszczak – klasy i strony
naszej aplikacji (o tym za chwilkę), - /src/main/webapp/WEB-INF – konfiguracja, w
naszym wypadku plik web.xml.
I to tyle. O resztę – biblioteki i inne niezbędne
pliki – zadba maven podczas budowania projektu.
Na co więc czekamy? Napiszmy kod naszej
pierwszej aplikacji.
Będzie się ona składała z jednej strony o nazwie
HelloWorld. Przejdź do katalogu /src/main/java/pl/staniszczak i usuń z niego wszystkie pliki
– nie będą one nam potrzebne. Utwórz teraz w
nim nową stronę internetową w pliku HelloWorld.
html:
Witaj świecie
Witaj Świecie
Gdy skończysz, utwórz klasę strony – Hello-
World.java. We frameworku Wicket każdej stronie
HTML odpowiada klasa Javy, która musi ma taką
samą nazwę (patrz nazwy plików) i znajdować się
w tym samym katalogu (pakiecie)
package pl.staniszczak;
import org.apache.wicket.markup.html.WebPage;
public class HelloWorld extends WebPage {
}
W naszym pierwszym przykładzie wyświetlamy
jedynie w przeglądarce napis Witaj Świecie. Nasza
klasa nie robi zatem nic więc – musi jedynie dziedziczyć
po klasie WebPage. Każda strona w Wicket
dziedziczy po klasie WebPage.
Utwórzmy jeszcze główną klasę aplikacji:
package pl.staniszczak;
import org.apache.wicket.protocol.http.WebApplication;
public class HelloWorldApplication extends WebApplication {
public Class getHomePage() {
return HelloWorld.class;
}
}
Klasa aplikacji musi dziedziczyć po klasie
WebApplication oraz dostarczać implementacji
abstrakcyjnej metody getHelloPage(). Metoda ta
wskazuje na klasę będącą główną stroną aplikacji.
W naszym wypadku jest to klasa HelloWorld.
Pozostało jeszcze zadbać o konfigurację
aplikacji. W katalogu /src/main/webapp/WEB-INF
znajduje się plik web.xml:
HelloWorld
wicket.HelloWorld
org.apache.wicket.protocol.http.WicketFilter
applicationClassName
pl.staniszczak.HelloWorldApplication
wicket.HelloWorld
/*
Tutaj należy w bloku filter -> filter-param w
parametrze applicationClassName ustawić klasę
naszej aplikacji, czyli HelloWorldAppliaction, podając
ją wraz z pakietem, w którym się ona znajduje.
I to wszytko. Teraz w linii poleceń przejdź do
katalogu projektu, a więc do katalogu HelloWorld.
Będąc w nim, wydaj polecenie (zanim to zrobisz,
usuń wszystkie pliki z katalogu /src/test/java/pl/staniszczak
– zawiera on pliki testów aplikacji, jednak
nie jest to tematem tego artykułu – pamiętaj o ich
usunięciu także w przypadku naszego kolejnego
projektu) widoczne na rysunku 3:
mvn clean install
Tak jak poprzednio, pierwsze wykonanie tego
polecenia może trwać dość długo.
Pozostało już tylko uruchomić Jetty i sprawdzić,
jak wygląda nasze dzieło w przeglądarce. W linii
poleceń wpisz:
mvn jetty:run
Gdy Jetty zostanie uruchomiony (rysunek 4), w
przeglądarce wczytaj stronę {stala}http://localhost:8080/HelloWorld/{/stala} – efekt widoczny jest na rysunku 5.
Hello… Jak Ci na imię?
Abyś mógł łatwo porównać Wicketa z opisywanym
niedawno na łamach \”Internet Makera\”
frameworka Tapestry, kolejny przykład będzie
polegał na wykonaniu tego samego zadania co
w artykule o Tapestry. Nasza aplikacja wyświetla
formularz, prosi o podanie imienia, a następnie
wita użytkownika, używając podanego wcześniej
imienia.
Stwórzmy w tym celu nowy projekt:
mvn archetype:create
-DarchetypeGroupId=org.apache.wicket
-DarchetypeArtifactId=wicket-archetypequickstart
-DarchetypeVersion=1.3.1
-DgroupId=pl.staniszczak
-DartifactId=Hello
Tak jak poprzednio, usuń wszystkie pliki z katalogów
/src/main/java/pl/staniszczak oraz /src/test/java/pl/staniszczak.
Ponownie zaczynamy od utworzenia strony w
języku HTML – tym razem jest to strona formularza:
Witaj!
Stronę tę zapisz w pliku HelloForm.html. Całość
wygląda jak HTML, z wyjątkiem:
- – {html}xmlns:wicket=\”http://wicket.apache.org{/html}\”
– definiuje prefiks wicket, określający przestrzeń
nazw dla znaczników i parametrów Wicketa w
HTML-u (a właściwie XML-u). Nie musimy podawać
tej definicji w znaczniku html, jeśli zawsze
używanym przez nas prefiksem określającym
przestrzeń nazw Wicketa będzie wyraz wicket. - – znacznik wicket:id – definiuje nazwę znaczników,
która będzie używana przez nas w kodzie
Javy.
I jak się już zapewne domyślasz, do powyższej
strony trzeba dopisać klasę HelloForm w Javie:
package pl.staniszczak;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;
public class HelloForm extends WebPage {
private Model model;
public HelloForm() {
Form form = new Form(\"frm\") {
protected void onSubmit() {
Hello hello = new Hello((String)model.getObject());
setResponsePage(hello);
}
};
model = new Model();
TextField imie = new TextField(\"imie\", model);
form.add(imie);
add(form);
}
}
Zanim przejdziemy do analizy powyższego
kodu, zadbajmy jeszcze o utworzenie strony
wyświetlającej wynik, czyli nasze powitanie. Plik
Hello.html:
Witaj!
Nazywasz się Imie. Witaj!
A także klasa obsługująca powyższą stronę:
package pl.staniszczak;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
public class Hello extends WebPage {
public Hello(String imie) {
add(new Label(\"imie\", imie));
}
}
Analizę klas rozpocznijmy od klasy Hello, jako
że jest ona prostsza. Metoda add dodaje elementy (komponenty) na stronę. Tutaj dodawanym komponentem
jest etykieta (Label), która umieszczana jest
na stronie w miejsce znacznika z identyfikatorem
(wicket:id) imie. Treść, jaka ma się na tej etykiecie
znaleźć, pochodzi ze zmiennej imie.
Klasa HelloForm jest nieco bardziej złożona.
Pierwszym tworzonym komponentem jest klasa
dziedzicząca po klasie Form, dostarczająca implementacji
abstrakcyjnej metody onSubmit().
W naszym przykładzie tworzymy klasę anonimową:
Form form = new Form(\"frm\") {
protected void onSubmit() {
Hello hello = new Hello((String)model.getObject());
setResponsePage(hello);
}
};
Klasa ta odnosi się do formularza ze strony
internetowej o identyfikatorze frm. Jak łatwo się
domyślić, metoda onSubmit() zostanie wywołana
po wciśnięciu przez użytkownika przycisku submit
w formularzu. Połączenie klasy formularza
ze stroną dokonuje się po dodaniu formularza
do strony:
add(form);
Poniższy kod:
model = new Model();
TextField imie = new TextField(\"imie\", model);
form.add(imie);
tworzy obiekt modelu – jest to swojego rodzaju
kontener służący do przechowywania danych
różnego typu. Następnie tworzy pole tekstowe
(TextField) powiązane z elementem strony internetowej
o identyfikatorze imie. Wartość przekazana
za pomocą tego pola pamiętana będzie w modelu.
Ostatnia linia powyższego kodu dodaje pole
tekstowe do formularza.
Wróćmy teraz na chwilkę do metody onSubmit()
formularza. W niej tworzony jest obiekt strony
Hello, a do jej konstruktora przekazywana jest
wartość pobrana z pola tekstowego za pomocą
modelu. Tak przygotowany obiekt strony wyniku
jest wyświetlany (setResponsePage()).
I to wszytko!
Musisz jeszcze utworzyć główną klasę aplikacji.
Jest ona jednak analogiczna do klasy z poprzedniego,
prostego przykładu:
package pl.staniszczak;
import org.apache.wicket.protocol.http.WebApplication;
public class HelloApplication extends WebApplication {
public Class getHomePage() {
return HelloForm.class;
}
}
Teraz zmodyfikuj wpis w pliku web.xml, zbuduj
projekt i uruchom Jetty. Gdy już to zrobisz, wystarczy,
że w przeglądarce wpiszesz adres {stala}http://localhost:8080/Hello/{/stala}, a będziesz mógł przetestować
swój pierwszy formularz zbudowany za pomocą
frameworka Wicket – zobacz rysunki 6 i 7.
Zakończenie
Frameworki Wicket i Tapestry są podobne i różne
zarazem. Przyświeca im ta sama idea – oddzielić
maksymalnie warstwę prezentacji (HTML) od
kodu, ale każdy z nich został wykonany inaczej.
Które rozwiązanie jest lepsze? Każdy powinien
sam wybrać to, co mu bardziej odpowiada. Wicket
wydaje się być prostszy, jednak przy bardziej złożonych
aplikacjach kod jego stron WWW może stać
się mniej czytelny. Z drugiej strony Tapestry jest
trudniejszy w opanowaniu, szczególnie gdy nie korzysta
się z adnotacji. Warto poznać oba frameworki
i następnie samemu wybrać zwycięzcę.