July 8, 2020
Hot Topics:

Wicket: The First Steps

  • By Karthik Gurumurthy
  • Send Email »
  • More Articles »

All Wicket pages extend the WebPage class. There is a one-to-one correspondence between the HTML widgets with a wicket:id attribute and the Page components. The HTML template could in fact be termed a view with the actual component hierarchy being described in the Page class. Wicket components need to be supplied with an id parameter and an Imodel implementation during construction (some exceptions will be discussed in the section "How to Specify a CompoundPropertyModel for a Page"). The model object acts as the source of data for the component. The component's id value must match the wicket:id attribute of the template's corresponding HTML component. Essentially, if the wicket:id of an HTML text element is name, the corresponding Wicket's TextField class with an ID of name needs to be added to the Page class. When a page is requested, Wicket knows the HTML template it maps to (it looks for a template whose name is the same as the Page class with an .html extension in a folder location that mimics the Page class package). During the page render phase, Wicket does the following:

  1. It kicks off the page rendering process by calling the Page.render() method.
  2. The Page locates the corresponding markup template and begins iterating over the HTML tags, converting them into an internal Java representation in the process.
  3. If a tag without wicket:id is found, it is rendered as is.
  4. If a tag with wicket:id is found, the corresponding Wicket component in the Page is located, and the rendering is delegated to the component.
  5. The Page instance is then stored in an internal store called PageMap. Wicket maintains one PageMap per user session.

The following illustrates this HTML widgets-Page components correspondence:

Click here for a larger image.


In Wicket, the component hierarchy is specified explicitly through Java code-which allows you to modularize code and reuse components via all the standard abstraction features of a modern object-oriented language. This is quite different from other frameworks like Tapestry, wherein the page components are typically specified in an XML page specification file listing the components used in the page. (Tapestry 4 makes even this page specification optional.)

It's always good to have the application pages extend from a base page class. One of the reasons to do so is that functionality common to all actions can be placed in the base class. Let's define an AppBasePage that all pages will extend, as shown in Listing 5. It currently does nothing. Set AppBasePage as Login page's superclass.

Listing 5. AppBasePage.java

public class AppBasePage extends WebPage {
  public AppBasePage(){

You can liken Wicket development to Swing development. A Swing application will typically have a main class that kicks off the application. Wicket also has one. A class that extends WebApplication informs Wicket of the home page that users first see when they access the application. The Application class may specify other Wicket page classes that have special meaning to an application (e.g., error display pages). The Application class in Listing 6 identifies the home page.

Listing 6. HelloWorldApplication.java

package com.apress.wicketbook.forms;

import wicket.protocol.http.WebApplication;

public class HelloWorldApplication extends WebApplication {

    public HelloWorldApplication(){}

    public Class getHomePage(){
      return Login.class;

Now that you are done registering the web application main class, start Tomcat and see whether the application starts up:

The Eclipse console seems to suggest otherwise and for a good reason. The stack trace seems to reveal that a Wicket class named ContextParamWebApplicationFactory failed to create the WebApplication class in the first place! Note that the factory class implements the IWebApplicationFactory interface.

Specifying IwebApplicationFactory Implementation

WicketServlet expects to be supplied with an IWebApplicationFactory implementation in order to delegate the responsibility of creating the WebApplication class. A factory implementation could be specified as a servlet initialization parameter in web.xml against the key application FactoryClassName. In the absence of such an entry, WicketServlet uses ContextParamWebApplicationFactory by default. As the name suggests, this class looks up a servlet context parameter to determine the WebApplication class name. The expected web.xml param-name in this case is applicationClassName. ContextParamWebApplicationFactory works perfectly for majority of the cases. But there is at least one scenario that requires a different implementation be specified.

Let's specify this important piece of information in the web.xml file as an initial parameter to WicketServlet. Listing 7 presents the modified web.xml.

Listing 7. web.xml Modified to Specify the Application Class Name

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.
  //DTD Web Application 2.3//EN"
  <display-name>Wicket Shop</display-name>

       <!-- HelloWorldApplication is the WebApplication class -->




Now start Tomcat and verify that things are OK:

Congratulations! Your first Wicket web application is up and running!

Enter the URL http://localhost:8080/wicket/helloworld in your browser and the login page should show up. Since you have already informed Wicket that the login page is your home page, it will render it by default.

Just to make sure that you aren't celebrating too soon, enter wicket-user as both user name and password on the login page and click Login. You should see the login and the password you typed in getting printed to the console.

But how did Wicket manage to get to the correct Page class instance to the Form component and then invoke the onSubmit() listener method? You will find out next.

What Happened on Form Submit?

Right-click the login page and select View Source. The actual HTML rendered on the browser looks like this:

  <title>Hello World</title>

    <script type="text/javascript"
   <script type="text/javascript">
        var pagemapcookie = getWicketCookie('pm-null/wicketHelloWorldApplication');
        if(!pagemapcookie && pagemapcookie != '1')
        else {document.location.href = '/wicket/helloworld;

  <body onUnLoad="deleteWicketCookie('pm-null/wicketHelloWorldApplication');">

    <form action="/wicket/helloworld;jsessionid=15o9ti4t9rn59?wicket:interface=:0:
loginForm::IFormSubmitListener" wicket:id="loginForm" method="post"
      <input type="hidden" name="loginForm:hf:0" id="loginForm:hf:0"/>
      User Name <input value="" type="text" wicket:id="userId"      name="userId"/><br/>
      Password <input value="" type="password" wicket:id="password"
      <input type="submit" value="Login"/>

The Form's action value is of interest:

  • /wicket/helloworld: This ensures the request makes it to the WicketServlet. (Ignore the jsessionid for now.) Then Wicket takes over.
  • wicket:interface: See the last entry in this list.
  • :0: In the PageMap, this looks for a page instance with ID 0. This is the Login page instance that got instantiated on first access to the Page.
  • :loginForm: In the Page in question, find the component with ID loginForm.
  • ::IFormSubmitListener: Invoke the callback method specified in the IFormSubmitListener interface (specified by wicket:interface) on that component.

loginForm is a Form instance that indeed implements the IFormSubmitListener interface. Hence this results in a call to the Form.onFormSubmitted() method. onFormSubmitted, in addition to other things, does the following:

  1. It converts the request parameters to the appropriate type as indicated by the backing model.
  2. It validates the Form components that in turn validate its child components.
  3. When the child components are found to be valid, it pushes the data from request into the component model.
  4. Finally, it calls onSubmit().

Thus, by the time your onSubmit() is called, Wicket makes sure that the model object corresponding to all the nested form components are appropriately updated, and that is when you print out the updated model values. For now, ignore the component validation step.

This is often referred to as a postback mechanism, in which the page that renders a form or view also handles user interactions with the rendered screen.

Page 2 of 6

This article was originally published on April 23, 2007

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date