Wicket: Java framework per applicazioni web

I parte: Introduzione e primi esempidi

Comincia con questo numero una serie su Wicket, un Java framework open source a componenti per applicazioni web. In questo primo articolo verranno illustrate l‘architettura e le principali features del framework e verrà mostrato un primo semplice esempio pratico di applicazione.

Wicket è un Java framework a componenti che consente di realizzare applicazioni web sfruttando appieno le potenzialità dei Plain Old Java Object (POJO), di HTML, di AJAX, di Spring e dell'IoC (Inversion of Control) pattern, di Hibernate o di iBatis. Wicket gestisce automaticamente lo stato degli oggetti a livello dei componenti: questo significa che non è necessario impazzire con la  gestione dedicata degli HTTPSession objects.

Wicket è open source e rilasciato con licenza Apache. È scaricabile dal sito ufficiale http://wicket.apache.org. La versione a cui faremo riferimento in questa serie di articoli è la 1.4-m2. A partire dalla versione 1.4 Wicket richiede Java 1.5. o release successiva.

Architettura del framework

Wicket porta il modello di programmazione a eventi di Swing nell'ambito dello sviluppo di applicazioni web. Il framework consente una netta separazione fra i ruoli di page designer HTML e sviluppatore Java poichè supporta l'utilizzo di template HTML puri che possono essere lavorati con un qualsiasi editor HTML WYSIWYG. Infatti il framework non richiede l'aggiunta di propri tag all'HTML: ai tag viene aggiunto solamente l'attributo wicket:id per i componenti che devono essere trattati dalla parte Java.

Wicket si contrappone alla natura stateless del linguaggio HTML mettendo componenti stateful a disposizione di chi sviluppa. Inoltre consente di realizzare rich client application nel pieno rispetto delle regole della programmazione object-oriented. Il framework è suddiviso in più librerie:

  • wicket-x.x.jar: il core del framework;
  • wicket-extensions-x.x.jar: le principali estensioni del framework;
  • wicket-datetime-x.x.jar: utilities per la manipolazione di date;
  • wicket-ioc-x.x.jar: implementazione del pattern Inversion of Control;
  • wicket-spring-x.x.jar: per l'integrazione con Spring (http://www.springframework.org/);
  • wicket-velocity-x.x.jar: per l'integrazione con Velocity (http://velocity.apache.org/);
  • wicket-guice-x.x.jar: per l'integrazione con Google Guice Ioc container (http://code.google.com/p/google-guice/);
  • wicket-auth-roles-x.x.jar: per la gestione dell'autenticazione e delle autorizzazioni nelle pagine web;
  • wicket-jmx-x.x.jar: interfaccia verso JMX;
  • wicket-objectssizeof-agent-x.x.jar: agent per object size measurements in caso di instrumentazione.

Le figure 1 e 2 mostrano due esempi di componenti facilmente implementabili con Wicket.

 Figura 1 - Form che utilizza il field per l'upload multiplo di file

 

Figura 2 - Tree Table

 

La prima applicazione di esempio

Vediamo adesso come implementare una semplice applicazione web Wicket-based per capire come è fatta la sua struttura tipica. Le considerazioni fatte in questo paragrafo sono generiche: valgono per tutte le applicazioni web Wicket-based, anche per quelle più complesse. La prima cosa da fare è registrare e mappare la Wicket Servlet nel web deployment descriptor (web.xml):

    WicketExamplesApplication
        org.apache.wicket.protocol.http.WicketServlet
        
        applicationClassName
        it.wicketexamples1.WicketExamplesApplication
        
        1

    

    WicketExamplesApplication
    /*

 

L'unico parametro che passiamo alla WicketServlet in fase di inizializzazione è il nome della WebApplication class della nostra applicazione. La WebApplication in Wicket è la main class che esegue il kick off dell'applicazione. Deve estendere la classe

 

org.apache.wicket.protocol.http.WebApplication

In essa va registrata la site map dell'applicazione. È l'unico punto in cui ciò viene fatto. Nella WebApplication class va indicato inoltre qual è la start page.

 

public class WicketExamplesApplication extends WebApplication {
    
    public WicketExamplesApplication() {

    }

    @Override
    protected void init() {
        super.init();
        
        //Disable Ajax Debug
        getDebugSettings().setAjaxDebugModeEnabled(false);
        
        // Register main page
        mountBookmarkablePage("/main", MainPage.class);
        
        // Register comment page
        mountBookmarkablePage("/comment", CommentPage.class);
    }
    
    /**
     * Marks home page.
     *
     */
    public Class getHomePage() {
        return MainPage.class;
    }

}

 

In questo esempio abbiamo registrato due web page (MainPage e CommentPage) e indicato come home page, fra le due, la MainPage. Entrambe le pagine, come tutte le Wicket Page, devono estendere la classe

org.apache.wicket.markup.html.WebPage

Ad ogni Java WebPage deve corrispondere un template HTML avente lo stesso nome della classe che deve essere presente nello stesso path della classe all'interno del classpath applicativo (vedi figura 3).

Figura 3 - Classpath dell'applicazione di esempio

Ci deve essere una corrispondenza 1:1 tra i widget HTML aventi l'attributo wicket:id e i componenti della WebPage. Il valore di wicket:id è univoco. Il codice del template HTML della Main page è il seguente:

                
        Message goes here
        

        Add a comment

I widget che hanno l'attributo wicket:id sono due, lo span message e l'anchor commentLink. Quindi la WebPage corrispondente avrà due component, uno di tipo

org.apache.wicket.markup.html.basic.Label

 

e l'altro di tipo

 

org.apache.wicket.markup.html.link.Link:

 

 

 

public class MainPage extends WebPage {
    public MainPage() {
        add(new Label("message", "This is my today's post!"));
        
        add(new Link("commentLink") {
            public void onClick() {
                setResponsePage(CommentPage.class);
            }
        });
    }
}

A runtime, durante la fase di render di una pagina, Wicket invoca il metodo WebPage.render(). La WebPage identifica il template corrispondente e inizia il parse dell'HTML. Per ogni tag che possiede l'attributo wicket:id viene ricercato nella WebPage il Wicket component corrispondente (avente lo stesso wicket:id value) e il rendering viene delegato a tale component. L'istanza di WebPage viene memorizzata in un internal store di tipo org.apache.wicket.PageMap. Wicket mantiene una PageMap per ogni sessione utente. La Main page della nostra applicazione, accessibile da browser invocando l'URL

http://localhost:/

avrà l'aspetto mostrato in figura 4.

Figura 4 - Main Page

Dal link presente nella pagina è possibile accedere alla CommentPage (figura 5):

Figura 5 - Comment Page

 

Il codice HTML di questa ulteriore pagina è il seguente:

 

                
Add your comment here:



 
1/1/2004

Comment text goes here.
 
1/2/2004

More comment text here.
 

Mentre il codice della corrispondente classe Java è:

public class CommentPage extends WebPage {
    private List commentList = new ArrayList();
    private ListView commentListView;
    
    public CommentPage() {
        add(new CommentForm("commentForm"));
        add(commentListView = new ListView("comments", commentList) {
            public void populateItem(final ListItem listItem) {
                final Comment comment = (Comment)listItem.getModelObject();
                listItem.add(new Label("date", comment.getDate().toString()));
                listItem.add(new MultiLineLabel("text", comment.getText()));
            }
        });
    }
    
    public class CommentForm extends Form {
        private final Comment comment = new Comment();
        
        public CommentForm(final String componentName) {
            super(componentName);
            add(new TextArea("text", new PropertyModel(comment, "text")));
        }
        
        public final void onSubmit() {
            final Comment newComment = new Comment();
            newComment.setText(comment.getText());
            
            commentList.add(0, newComment);
            commentListView.modelChanged();
        
            comment.setText("");
        }
    }
    
}

 

Il codice dell'applicazione di esempio può essere scaricato dal menu in alto a sinistra (WicketExamples1). L'archivio non comprende le librerie necessarie per la compilazione e/o il runtime. Le dipendenze sono le seguenti:

 

  • wicket-1.4-m2.jar (compilazione e runtime)
  • slf4j-api-1.5.0.jar (runtime)
  • slf4j-jcl-1.5.0.jar (runtime)

 

Conclusioni

In questo primo articolo è stata data a grandi linee una descrizione del framework. Nel prossimo articolo ne vedremo più in dettaglio componenti e caratteristiche più avanzate.

Riferimenti

[1] Karthik Gurumurthy, "Pro Wicket", Apress, 2006

[2] Sito ufficiale di Wicket presso Apache
http://wicket.apache.org/

 

 

 

Condividi

Pubblicato nel numero
131 luglio 2008
Guglielmo Iozzia si è Laureato nel 1999 in Ingegneria Elettronica (indirizzo Biomedico) presso l‘Università di Bologna. Ha progettato e realizzato un software diagnostico per la predizione dell‘andamento della pressione intracranica in pazienti in terapia intensiva neurochirurgica. Frequenta il mondo Java dall‘inizio del 2000. Dopo numerose esperienze presso un‘azienda di Bologna…
Articoli nella stessa serie
Ti potrebbe interessare anche