Nella miriade di web framework scritti per Java, ho preso in considerazione e apprezzato, Apache Wicket.
I Framework a componenti in Java, vedono il loro massimo esponente nelle Java ServerFaces di Sun, ma queste ultime non mi hanno mai pienamente convinto per i seguenti motivi:
-
non sono immediate, ci vuole sempre un po’ di tempo per entrare nella loro ottica
-
è difficile creare dei componenti riutilizzabili in maniera orizzontale in più applicazioni
-
è un framework abbastanza pesante come utilizzo di risorse
-
mi oriento male fra le varie implementazioni e sottoframewok che si appoggiano alle JSF
Per questo motivo ho iniziato a giocare con Wicket, e ne sono rimasto soddisfatto.
Wicket si basa sulla modellazione ad oggetti di tutto il vostro applicativo web, quindi l’applicazione, le pagine, i componenti html sono gestiti come Oggetti e godono di tutti i benefici della programmazione OO. Per le pagine si utilizza un meccanismo di template dove queste vengono rese in base a delle vere e proprie pagine html con riferimenti ai vostri oggetti. Questi template sono delle vere e proprie pagine html e quindi creabili e componibili con qualsiasi editor WYSIWYG.
Vediamo i concetti principali di una applicazione Wicket.
L’applicazione
public class MyApplication extends WebApplication {
public MyApplication() {
}
@Override
public Session newSession(Request req, Response resp) {
return new MySession(req);
}
public Class getHomePage() {
return ConnectionPage.class;
}
@Override
protected void init() {
super.init();
mount(new IndexedParamUrlCodingStrategy(”/connection”, ConnectionPage.class));
mount(new IndexedParamUrlCodingStrategy(”/table”, TablePage.class));
mount(new IndexedParamUrlCodingStrategy(”/home”, AddTablePage.class));
// initialize velocity
try {
Velocity.init();
}
catch (Exception e) {
throw new WicketRuntimeException(e);
}
}
}
Per illustrare una applicazione prendo ad esempio una mia classe. Per ogni progetto (war) esiste una classe che modella l’applicazione. La vostra classe deve estendere la Classe WebApplication. Di che cosa si occupa la WebApplication? Principalmente di gestire le pagine, di specificare la HomePage, e tutti quei concetti dell’http quali la sessione, la request e la response, che verranno nascosti alle pagine sottostanti. Questa è l’unica classe che verrà mappata nel web.xml.
La pagina
Le pagine in wicket si compongono di 2 componenti. La vera e propria Classe Java che estende la WebPage e il template html che deve avere lo stesso nome della classe e risiedere nello stesso package.
AddTablePage.java
public class AddTablePage extends WebPage{
public AddTablePage() {
add(new Label(”label1″, “Add a new table” ));
}
}
Come noterete nel costruttore della pagina vengono aggiunti con il metodo add tutti i componenti. Nel caso sopra ho aggiunto una label a cui ho dato il riferimento “label1” e gli ho associato un modello statico definito grazie alla stringa “Add a new table”.
Wicket ha diversi componenti: quelli base che definiscono oggetti html (form, bottoni, campi a scelta multipla,…), e quelli più aggregati e complessi che racchiudono più funzionalità: tabelle paginate, viste ad albero, componenti ajax…
AddTablePage.html
<html>
<head>
<title>Add a new Table</title>
</head>
<body>
<h1><span wicket:id=”label”>Add a new Table</span></h1>
</body>
</html>
La pagina html mappa il riferimento definito nella WebPage nel proprio html, nel caso di una label si utilizza il tag span, ma a seconda del tipo di componente il wicket:id può essere aggiunto a tag input, form, select…
Il modello
Wicket utilizza i modelli (da non confondere con il Model del paradigma MVC), per mappare gli oggetti (che mutano il loro stato a Runtime attraverso l’interazione con l’utente) associati ai componenti “html” statici creati nei costruttori delle webpage.
I modelli Wicket estendono una semplice interfaccia IModel, che necessita di due soli metodi setObject e getObject.
public interface IModel {
public Object getObject();
public void setObject(final Object object);
}
La natura dell’Oggetto del Modello dipende dal tipo di componente a cui è associato. Ad esempio sarà una stringa per una label, ma può essere una Collection per una lista.
Attraverso l’implementazione di questa interfaccia potete fare tutto quello che vi serve per i vostri componenti Wicket, giocando solo sul set e get dell’Object, ed è qui che all’inizio si troveranno le maggiori difficoltà e gli errori più comuni. Ma presa padronanza con questo concetto, programmare in Wicket diventerà semplicissimo e molto veloce.
In ogni caso Wicket offrè già delle implementazioni di questa interfaccia le più comuni sono:
- dynamic Model, es new Model(final Object modelObject) associa modelObject ad un modello e questo cambierà lo stato dell’Oggetto
- PropertyModel(final Object modelObject, final String expression) Lega un modello ad una proprietà di un oggetto
- WrappedObjectModel, si possono comporre modelli innestandoli fra di loro (in pratica un IModel diventa l’objectModel di un altro modello). Molto utili per la modellazione di strutture complesse
Il componente
Ho detto prima della facilità di Wicket di estendersi e creare nuovi componenti riutilizabili. Questo viene fatto tramite l’uso (ma non solo guardatevi la documentazione) di Pannelli.
Un pannello (panel) è simile ad una WebPage, quindi ha un suo modello, i suoi componenti e il suo template html per il rendering e poi può essere incluso nelle webpage come qualsiasi altro componente.
Riporto alcuni stralci di codice per esempio.
public class DBParamPanel extends Panel {
public DBParamPanel(String s, final MDConnectionParam conn) {
super(s);
BoundCompoundPropertyModel cm = new BoundCompoundPropertyModel(conn);
DBParamSelector param = new DBParamSelector(”choices”);
Form form = new DBParamForm(”form”, cm);
add(form);
form.add(param);
cm.bind(param, “type”);
}
…
L’html
<wicket:panel>
<fieldset>
<legend>Create Connection params</legend>
<form wicket:id=”form”>
<select wicket:id=”choices”/><br/>
<table border=”0″>
…
</form>
</fieldset>
</wicket:panel>
La pagina che include il Pannello
public class ConnectionPage extends
WebPage {
public ConnectionPage(final
PageParameters parameters) throws Exception {
super(parameters);
..
DBParamPanel createConnection =
new DBParamPanel("createconn", new MDConnectionParam());
...
add(createConnection);
...
}
<?xml version=”1.0″ encoding=”UTF-8″?>
<span wicket:id=”listPanel”/>
<span wicket:id=”createconn”/>
<span wicket:id=”editPanel”/>
Andiamo oltre
Questo era un breve articolo di introduzione a wicket. Nella mia breve esperienza ad un certo punto mi sono scontrato con il limite dei template html dove tutto deve essere conosciuto a priori… Ma anche in questo caso wicket mi da una mano permettendomi di usare Apache Velocity (o se preferite FreeMarker) per creare dinamicamente dell’Html e qui si aprono nuovi scenari…