Wicket – It can do Ajax without writing any line of Javascript!

2

Wicket is around for a while, but lately it is getting more and more attention. A few years ago I attended a presentation about Wicket. It looked like a nice framework, but at that time I didn’t see much differences with Tapestry and put it on my list of nice frameworks. A few weeks ago a colleague told me some site was comparing Wicket with GWT. We both found that a bit strange, so I took a look at Wicket to see what became of it. It seems like Wicket can create Ajax-things for you without writing any Javascript (just like GWT, but that’s probably one of the few similarities). That’s what this blog is about. It gives a short introduction to Wicket and shows you how to create your first Ajax-call. This isn’t a getting started guide, there are many guides around (which can be found in the conclusion), I just focus on the Ajax-functionality here.
....

Wicket is a web framework that is a little bit different than most web frameworks we know. It doesn’t use jsp, but instead you can annotate html tags with a wicket attribute. The wicket attributes are referenced from within java code and the annotated tags become java objects.

The easiest way to get started with Wicket is creating a Wicket archetype with Maven 2. On the Wicket site you can generate a command to create a Maven 2 project.

You can set the groupId and artifactId and after that you have to pick a version. All you have to do now is copy the command and run it in a command line window (Maven 2 needs to be installed). This is the first time I’ve seen this and I hope other frameworks/libraries will copy this, it’s always a bit of a hustle to get started with a new framework and now it only takes a few seconds!
The final step is creating the files for  your IDE (http://wicket.apache.org/quickstart.html scroll down to the bottom) and open your IDE to browse the generated project.

The first thing that catches the eye is that there is no servlet for Wicket inside the web.xml, most web frameworks use a servlet, Wicket only needs a filter. The filter points to a class that is the heart of your application, in this case WicketApplication.
WicketApplication is a class that extends the WebApplication class. Inside the WicketApplication you have to override the getHomePage method. This is the starting point of your application and determines the first page the user will see.
With the archetype you get a page called HomePage. The page consists of a .java and .html file. The java file is the class that is returned inside the getHomePage method in WicketApplication. The .html is just an ordinary .html file with some the earlier mentioned wicket attributes. The HomePage page has a wicket:id=”message” on a span. This message is referenced inside HomePage.java:
add(new Label("message", "If you see this message wicket is properly configured and running"));
The first argument of the Label object is the id of the element (in the .html), the second argument is the value of Label as we will see it in the browser. Of course this text is displayed when we compile and deploy the application. Open the root of the web application (in my case http://localhost:8080/wicket) to see the result.

Now add comment slashes to skip the call to the add method in HomePage.java. After recompiling we get a very useful error message (and I’m not being ironic, I really like it when developers pay attention to their error messages):

WicketMessage: Unable to find component with id ‘message’ in [Page class = nl.amis.HomePage, id = 0, version = 0]. This means that you declared wicket:id=message in your markup, but that you either did not add the component to your page at all, or that the hierarchy does not match.
[markup = file:/D:/Documents/wicket-test/target/wicket-test/WEB-INF/classes/nl/amis/HomePage.html
Ok let’s put the add back and add Ajax to the page.

Adding ajax behaviour to your pages

And now the reason why I’m writing this blog, ajax behaviour without one line of Javascript!
On my page I want to display the status of the system (this is a String that lives in a static class). The initial status says “the application is started” and after a click on a link the status  must say: “the application is still running”, without refreshing the page of course!

Add a link to your HomePage.html: <a href="#" wicket:id="link">click me</a>

The java file needs some changes, in fact so many that I just paste my new class and explain what I’ve done:


public class HomePage extends WebPage {
    private static final long serialVersionUID = 1L;

    public HomePage(final PageParameters parameters) {

        final Model model = new Model() {
            public Object getObject() {
                return StatusService.getStatus();
            }
        };

        final Label label = new Label("message", model);
        label.setOutputMarkupId(true);

        add(label);

        add(new AjaxFallbackLink("link") {
            public void onClick(AjaxRequestTarget target) {
                System.out.println("onclick");
                StatusService.setStatus("Application is still running");
                target.addComponent(label);
            }
        });
    }
}

The link we just added to the .html needs to become an AjaxFallbackLink. A method must be invoked when the onclick event in Javascript is fired. With the AjaxFallbackLink there is an onclick method we can override. In this method the status is updated. When the status is updated the component must be added to the page again, with the addComponent method.
The Model object seems a bit strange, but in Wicket almost everything is an object, in this case the message of the Label is an Object and not a String.

When we load the page for the first time we see the initial state:

After clicking the link the status is updated:

Note that the page is not reloaded. Let’s analyze the ajax request:
<ajax-response>
<component id="message2">
<span wicket:id="message" id="message2">Application is still running</span>
</component>
</ajax-response>

This response is very clear, the component with id message2 needs to be refreshed with a new text. The AJAX-request can be analyzed in Firebug (when you see no response, click with the middle mouse button on the url, there are some problems rendering xml in Firebug I guess). Another option is the “WICKET AJAX DEBUG” on the bottom right corner of your page. Because we’re running in developer mode we can analyze the ajax traffic, very neat!

Conclusion

It seems Wicket really has evolved since the first time I saw it. I really like the way they ‘do’ Ajax. I  think I have some trouble getting used to using objects for everything (the Model object on the Label for example), but maybe it’s because I just started with Wicket. When you’re used to frameworks like Struts, Spring and Stripes you really have to take your time to get used to the component based structure of Wicket. It might be a bit difficult at first, but after a while you’ll see that it is very useful and the Wicket guys really thought about it.
The documentation and error messages are really good, they really helped me understand Wicket better.
If you want to start with Wicket I suggest reading the article on The Server Side and also don’t forget to check out the excellent samples on the Wicket page.

Sources

http://wicket.apache.org/index.html
http://wicket.apache.org/quickstart.html

Share.

About Author

2 Comments

  1. I need to enter substring of Name text box in another text box(shortname). I am unable to find component(shortname) using find component. Does any one know how this can be done?

  2. Cool article! You can pass a full-on IModel to label or you can just pass a String for convenience. The difference is that the IModel implementation could update dynamically, while the fixed string is static.