Thursday, September 13, 2007

Componenti in Wicket

Come abbiamo già detto Wicket consente lo sviluppo per componenti e di componenti HTML. L'architettura di Wicket prevede che un componente venga descritto tramite 3 tipologie di entità:

  • il component (java)
  • il model (java)
  • il markup (html)
L'interazione dei tre consente lo sviluppo di una entità completa, autonoma e riusabile tramite i costrutti nativi di Java. Fondamentalmente la parte component serve a rienpire dinamicamente alcune aree del markup utilizzando come valori i dati contenuti nel model.
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
Some example page
</title>
</head>
<body>
<span wicket:id="messaggio">
[message here]
</span>
</body>
l'area wicked:id indica al parser di ricercare un componente registratosi come "messaggio" all'interno della pagina. Questo rappresenta il component.
public class Hello extends WebPage {
   public Hello() {
       add(new Label("messaggio", "Mondo Wicket"));
   }
}
In questo caso è stato anche specificato il model, definito dalla stringa "Mondo Wicket". In altri casi, come vedremo, il model è una classe a sè che implementa l'interfaccia IModel. L'idea interessante proposta da Wicket è di usare una unica istanza della classe Component (o Page in questo caso) relegando il suo stato in un'altra classe (il Model) che viene gestito automaticamente dall'infrastruttura. La parte di markup viene usata soltanto per il rendering e l'utilizzo unicamente di attributi per l'associazione con la parte component fa sì che la pagina possa essere efficacemente editata con un qualsiasi editor html, senza richiedere particolari funzionalità.

Friday, August 10, 2007

Il primo esempio con Ajax

In questo esempio creeremo una pagina con un link che se premuto incrementerà di 1 il valore nella label di fianco. Come al solito dovremo modificare il web.xml per definire il gestore dell'applicazione (vedi su HelloWorld) e definire la classe estensione di WebApplication:


<servlet>
<servlet-name>AjaxLinkCounterApplication</servlet-name>
<servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>it.denzosoft.web.wicket.sample3.LinkCounterApplication</param-value>
</init-param>
<init-param>
<param-name>configuration</param-name>
<param-value>development</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AjaxLinkCounterApplication</servlet-name>
<url-pattern>/ajaxlinkcounter/*</url-pattern>
</servlet-mapping>

package it.denzosoft.web.wicket.sample3;

import wicket.Application;
import wicket.protocol.http.WebApplication;

public class LinkCounterApplication extends WebApplication {
public LinkCounterApplication() {
}

public Class getHomePage() {
  return LinkCounter.class;
}
}
Adesso definiamo il template della pagina (come al solito banalissimo HTML):
<html>
<body>
 <a href="#" wicket:id="link">This link</a> has been clicked >
 <span wicket:id="label">123</span> times. >
</body>
</html>
Infine definiamo la classe di model:
package it.denzosoft.web.wicket.sample3;

import wicket.ajax.AjaxRequestTarget;
import wicket.ajax.markup.html.AjaxFallbackLink;
import wicket.markup.html.WebPage;
import wicket.markup.html.basic.Label;
import wicket.model.PropertyModel;

public class LinkCounter extends WebPage {
private int counter;
private Label label;
public LinkCounter() {
add(new AjaxFallbackLink("link") {
    @Override
    public void onClick(AjaxRequestTarget target) {
        counter++;
        if(target != null) {
            target.addComponent(label);
        }
    }
});
label = new Label("label", new PropertyModel(this, "counter"));
label.setOutputMarkupId(true);
add(label);
}

public int getCounter() {
return counter;
}
}
A questo punto basterà deployare tramite NetBeans e chiamare l'opportuna url. Complimenti avete realizzato una applicazione Ajax con le seguenti caratteristiche:
  • non avete usato mai javascript
  • avete imparato che wicket ha componenti nativi che supportano Ajax
  • avete imparato che wicket è lo strumento ideale per lavorare con Ajax in quanto nasconde la complessità all'interno dei suoi componenti

HelloWorld in Wicket

In questo tutorial vedremo come realizzare una semplice applicazione web che produca la mitica frase "HelloWorld" sulla pagina visualizzata. I passi da seguire sembreranno tanti, ma come vedremo in seguito, molti sono una-tantum. Per cui mettiamoci con calma a lavorare. Io di solito uso NetBeans per lo sviluppo, ma ognuno può usare l'IDE che preferisce, tanto eseguiremo solo operazioni standard. 1. Bisogna scaricare l'ultima versione di Wicket da SourceForge.net (in attesa della pubblicazione della 1.3 attualmente in beta, ci riferiremo alle 1.2.6 ultima release stabile). 2. Si scompatta lo zip in una opportuna directory 3. Si avvia NetBeans, e si crea un nuovo progetto Web standard, quindi si aggiungono le seguenti librerie:
  • commons-logging-1.0.4.jar
  • log4j-1.2.13.jar
  • portlet-api-1.0.jar
  • servlet-api-2.3.jar
  • wicket-1.2.6.jar
tutte ricavate dallo zip di Wicket. 4. A questo punto si puù cominciare a lavorare, e per prima cosa modificheremo il web.xml in modo da attivare per determinate url la gestione con Wicket:
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xsi="http://www.w3.org/2001/XMLSchema-instance"
schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>HelloWorldApplication</servlet-name>
<servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
<init-param>
   <param-name>applicationClassName</param-name>  
   <param-value>it.denzosoft.web.wicket.sample1.HelloWorldApplication</param-value>
</init-param>
<init-param>  
   <param-name>configuration</param-name>
   <param-value>development</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>HelloWorldApplication</servlet-name>
<url-pattern>/helloworld/*</url-pattern>
</servlet-mapping>

<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
</web-app>

Alcuni commenti:
  • abbiamo definito una nuova applicazione Wicket (it.denzosoft.web.wicket.sample1.HelloWorldApplication) che verrà invocata quando sarà richiesta una url che corrisponde alla regola specificata (/helloworld/*). La classe in questione ha il ruolo fondamentale di definire tutte le proprietà dell'applicazione al posto di un file di configurazione ed attivare il caricamento della paggina di avvio.
  • alcuni dei parametri sono specificati direttamente nel file web.xml, ma potevano essere impostati nel metodo init di HelloWorldApplication
5. Prepariamo la classe che farà da gestore dell'applicazione Wicket. Vediamo questa classe com'è fatta:
package it.denzosoft.web.wicket.sample1;

import wicket.Application;
import wicket.protocol.http.WebApplication;

public class HelloWorldApplication extends WebApplication {
public HelloWorldApplication() {
}

public void init() {
String deploymentMode = getWicketServlet().getInitParameter(
     Application.CONFIGURATION);
configure(deploymentMode);
}

public Class getHomePage() {
return HelloWorld.class;
}
}
La classe estende wicket.protocol.http.WebApplication, nel metodo init definisce tutti i parametri di configurazione e nel metodo getHomePage() indica quale sarà la pagina da caricare all'avvio (rappresentata dalla sua classe di model). NB: la configurazione del deployment mode è stata fatta in doppio appunto per far vedere che si è liberi di definirla nel web.xml o a livello di applicazione. 6. Implementiamo la pagina che conterrà la scritta. In wicket una pagina è rappresentata da 2 entità: un template ed un model. I due file devono avere lo stesso nome (attenzione alle maiusole ed estensioni diversa: rispettivamente html e java). Il template rappresenta la struttura della pagina espressa sotto forma di HTML puro. Nel nostro caso, quindi sarà molto semplice (HelloWorld.html):
<html>
<body>
    <h1 wicket:id="message">[text goes here]</h1>
</body>
</html>
Questo template è scritto in perfetto html e può essere editato con qualsiasi strumento per la gestione dell'HTML (anche FrontPage, se non ci credete provate), l'unica caratteristica strana è la presenza di un attributo nuovo (wicket:id) che, in quanto non cososciuto, viene tranquillamente ignorato se volete provare una preview. La parte tra parentesi quadre è solo un esempio di contenuto che in fase di esecuzione verrà sovrascritta, quindi è lì solo per bellezza. Adesso passiamo alla classe di model: questa classe ha lo scopo di gestire lo stato della pagina e definire gli eventuali handler che risponderanno agli eventi generati sulla stessa.
package it.denzosoft.web.wicket.sample1;

import wicket.markup.html.WebPage;
import wicket.markup.html.basic.Label;

public class HelloWorld extends WebPage {
public HelloWorld() {
 add(new Label("message", "Hello, World!"));
}
}
Questa classe estense WebPage e nel costruttore dichiarerà i componenti da aggiungere al template in fase di rendering. In questo case si nota come il primo parametro del costruttore della label sia uguale all'attributo wicked:id definito nel template. In esecuzione la label verrà disegnata al posto del contenuto del tag che ha identico id. Lo sviluppo è finito e si può eseguire l'esempio richiamando la url: http://localhost:8084/WicketSample/helloworld/ se usate NetBeans. Complimenti, avete appena realizzato un'applicazione con Wicket e avete scoperto che:
  • wicket è estremamente java oriented
  • wicket non richiede file di configurazioni esterni, fa tutto la classe che gestisce l'application
  • wicket è basato su template che sono semplicissimi file HTML
  • wicket runtime sostituisce il contenuto di tag specifici con la renderizzazione di componenti java
  • wicket è page-based
  • wicket rappresenta le sue pagine attraverso la coppia template-model assicurando una completa separazione tra i 2 aspetti (non c'è Java nel template e non c'è HTML nelle classi)
  • wicked è componet-based
Ognuno di questi aspetti verrà ultriormente approfondito in seguito. Saluti

Confronto tra Wicket e i altri Framework

Se la domanda è: ma Wicket è meglio degli altri? La risposta è: dipende... Purtropo è sempre così! :( Qui di seguito vengono presentati un po' di link in cui è possibile confrontare Wicket rispetto agli altri framework più noti. http://www.virtuas.com/files/JavaWebFrameworkSweetSpots.pdf http://static.raibledesigns.com/repository/presentations/ComparingJavaWebFrameworks-OSCON2007.pdf http://static.raibledesigns.com/repository/presentations/ComparingJavaWebFrameworks.pdf http://gceclub.sun.com.cn/java_one_online/2005/TS-7642/ts-7642.pdf http://www.chariotsolutions.com/slides/spring-forward-2006-web-frameworks.pdf