10 lutego 2008

Model oparty o POJO w Wicket - CompoundPropertyModel

W rozdziale 1. Wicket: The First Steps książki Pro Wicket można przeczytać o kolejnej ciekawostce Wicketa - wykorzystanie POJO w modelu za pomocą klasy org.apache.wicket.model.CompoundPropertyModel.

Podobnie jak w JSF, model w Wicket nie jest w żaden sposób powiązany z wykorzystywanym szkieletem programistycznym i może być w całości oparty o POJO. Sam szkielet nie narzuca niczego poza przestrzeganiem zasad JavaBeans (nie mylić z Enterprise JavaBeans, która jest kompletnie inną specyfikacją).

Utworzyłem kolejną stronę DaneOsobowe (świadomie nie piszę DaneOsobowe.html, gdyż przez stronę w Wicket rozumiem parę DaneOsobowe.html oraz klasę DaneOsobowe.java).

Strona DaneOsobowe.html prezentuje się następująco:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Wicket Demo App</title>
</head>
<body>
<strong>Wicket Demo App</strong>
<form wicket:id="daneOsobowe" action="">
Imię: <input type="text" wicket:id="imie" /> <br>
Nazwisko: <input type="text" wicket:id="nazwisko" /> <br>
Login: <input type="text" wicket:id="login" /> <br>
<input type="submit" value="Zatwierdź" />
</form>
</body>
</html>
, której towarzyszy klasa pl.jaceklaskowski.wicket.DaneOsobowe
package pl.jaceklaskowski.wicket;

import org.apache.wicket.PageParameters;
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.CompoundPropertyModel;

import pl.jaceklaskowski.wicket.entities.Osoba;

public class DaneOsobowe extends WebPage {

private static final long serialVersionUID = 1L;

public DaneOsobowe(PageParameters params) {
Osoba osoba = new Osoba();
CompoundPropertyModel model = new CompoundPropertyModel(osoba);
Form loginForm = new Form("daneOsobowe", model) {
private static final long serialVersionUID = 1L;

public void onSubmit() {
// TODO: miejsce dla JPA
setResponsePage(new Powitanie(getModelObjectAsString()));
}
};
loginForm.add(new TextField("imie"));
loginForm.add(new TextField("nazwisko"));
loginForm.add(new TextField("login"));
add(loginForm);
}
}
Na uwagę zasługuje użycie klasy org.apache.wicket.model.CompoundPropertyModel, która przyjmuje jako parametr egzemplarz typu reprezentującego model w aplikacji (Osoba) będący POJO. Każdorazowo, kiedy należy ustawić/pobrać właściwość w modelu Wicket za pomocą CompoundPropertyModel ustawia je w związanym z nim egzemplarzu POJO. Otwiera się tym samym furtka do wprowadzenia JPA, gdzie encje będą modelem (ale o tym później, bo to już ogólnie wiadomo jak zrobić). Pozostaje przedstawić klasę pl.jaceklaskowski.wicket.entities.Osoba.
package pl.jaceklaskowski.wicket.entities;

import java.io.Serializable;
import java.text.MessageFormat;

public class Osoba implements Serializable {

private static final long serialVersionUID = 1L;
private String imie;
private String nazwisko;
private String login;

public String getImie() {
return imie;
}

public void setImie(String imie) {
this.imie = imie;
}

public String getNazwisko() {
return nazwisko;
}

public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String toString() {
return MessageFormat.format("{0} {1} - login: {2}", imie, nazwisko, login);
}

}
Dodatkowo dodałem mapowanie strony na odpowiedni adres w pl.jaceklaskowski.wicket.WicketDemoApplication. Tym samym każdorazowe wywołanie http://localhost:8080/wicket-demo/daneosobowe spowoduje wyświetlenie strony DaneOsobowe.html.
package pl.jaceklaskowski.wicket;

import org.apache.wicket.protocol.http.WebApplication;

public class WicketDemoApplication extends WebApplication {

protected void init() {
// upiększ URLe
mountBookmarkablePage("/home", HomePage.class);
mountBookmarkablePage("/daneosobowe", DaneOsobowe.class);
}

public Class getHomePage() {
return HomePage.class;
}

}
Dla przypomnienia napiszę, że tzw. strony bookmarkable są stronami, które można wywołać bezpośrednio (można utworzyć odnośnik), a więc im odpowiadające klasy posiadają bezparametrowy konstruktor lub konstruktor, który przyjmuje org.apache.wicket.PageParameters, który opakowuje parametry zlecenia.

p.s. Konkurs Blog Roku 2007 wciąż trwa, a Notatnik wciąż poza pierwszą 5-tką (!) Uplasował się na 9. miejscu z 67 głosami, co daje nam 5 kolejnych przekonanych o słuszności wysłania SMSa od wczoraj. Dziękuję wszystkim głosującym! Coś jednak nie mogę przekonać pozostałych czytelników Notatnika do wysłania SMSa o treści B00248 pod numer 71222, co przełoży się na pozycję mojego bloga w konkursie. Może tym razem? Wyślij i powiedz innym, aby wysłali.