Comparing Web Frameworks: Wicket

As you might be aware, Simon Brown has been creating a series of articles where he wants to compare different web frameworks that exist for Java. So far, he has set the requirements for what is going to be compared on the different frameworks, created a domain model and applied those rules using plain JSP, JSTL, XML and Struts (that’s the last link to Simon’s site, I promise).

Well, I asked him if he was considering Wicket among the list of web frameworks he’s evaluating, and since he wasn’t, I offered to do an article comparing Wicket. Simon was kind enough to provide me the source code for what he has done so far, so I could base my comparison on that. In particular, I’m using the same domain model that he’s using, since that is a part that should remain the same among the different web frameworks.

Why did I choose to write this article? Two main reasons. One, I get to learn a new web framework, and I’ve been told several times by various individuals that Wicket is a cool framework. The other reason is that I like to write about Java, although sometimes it doesn’t show. I tried to do this article since the end of January after Simon’s last post about Struts, and around that time I actually created the example, but the article took a little longer. I used Wicket 1.1.1 for my example, because when I created it, Wicket 1.2 was only available on CVS. Wicket 1.2 is now reaching beta stages, so I’ll probably post a follow up later (hopefully) of what has changed for Wicket 1.2.

So, what is Wicket? This is the description from the main site:

Wicket is a Java web application framework that takes simplicity, separation of concerns and ease of development to a whole new level. Wicket pages can be mocked up, previewed and later revised using standard WYSIWYG HTML design tools. Dynamic content processing and form handling is all handled in Java code using a first-class component model backed by POJO data beans that can easily be persisted using your favorite technology.

What that basically means is that Wicket separates the front-end visual design (HTML) from the back-end application logic (Java), using components (think Swing JComponents for the web). Instead of being another MVC framework, Wicket is more of an event-driven framework, like a traditional GUI. However, you could look at each ‘component’ as a tiny MVC with the ‘view’ part being the html code (but they won’t tell it like that). As you will see later, all the application logic falls inside the Java classes, instead of mixing it with the pages, like JSP (true separation of concerns). The Java code is glued to the HTML page by using a special wicket:id attribute that can be assigned to almost any HTML tag, and that tells Wicket where do you want to render a component. Wicket comes with several components like Labels, Links, Lists, etc., which are uniquely defined on a webpage by setting an Id to the component, and the content which is represented by a Model.

OK, so after that brief introduction, it’s time to discuss our example. From the requirements post (see above), I am going to need an application that displays 3 pages. One is the Home Page which shows a list of blog entries, another one is the Blog Detail Page that shows each blog entry, and a special Page Not Found page that will be displayed when the user is trying to access an invalid page (an invalid blog entry).

Now, Wicket itself has a couple of requirements, or rather best practices. The main one is that your web application needs to have a class that extends WebApplication. This is where Wicket starts to differentiate itself from other frameworks. Most other web frameworks I’ve seen are “hooked on XML”. To define pages and interactions, you need to write one or more XML files. For Struts you need to at least write a sruts-config.xml, and if you use tiles, you need another one. JSF has faces-config.xml among others. While I don’t see anything wrong in using XML, I do think that this approach scatters your logic, and it makes it a little more troublesome to do. If you’re using Wicket, there’s only one XML you really need to modify, web.xml, and this isn’t even a Wicket requirement, but rather a servlet specification requirement (i.e. you can’t make a servlet work if you don’t define it in the xml).

So, in our example, to define what servlet will handle the application, I have these lines inside web.xml:

<servlet>
  <servlet-name>blog</servlet-name>
  <servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
  <init-param>
    <param-name<applicationClassName</param-name>
    <param-value<org.javageek.wicket.BlogApplication</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>blog</servlet-name>
  <url-pattern>/app/*</url-pattern>
</servlet-mapping>

As you can see, we are defining a servlet, WicketServlet, that has, as one of its initialization parameters, the full classpath of the class that extends WebApplication, which is our main application class BlogApplication. This is what BlogApplication looks like:

package org.javageek.wicket;

import wicket.Application;
import wicket.ApplicationSettings;
import wicket.protocol.http.WebApplication;
import domain.Blog;
import domain.BlogService;

public class BlogApplication extends WebApplication {

  private BlogService blogService = new BlogService();

  public BlogApplication() {
    getPages().setHomePage(Index.class);
    ApplicationSettings settings = getSettings();
    settings.configure("development");
    settings.setStripWicketTags(true);
    settings.setDefaultMarkupEncoding("UTF-8");
    settings.setStripXmlDeclarationFromOutput(false);
    settings.setBufferResponse(false);
    settings.setRenderStrategy(ApplicationSettings.REDIRECT_TO_RENDER);
  }

  public static final BlogApplication instance() {
    return (BlogApplication)Application.get();
  }

  public Blog getBlog() {
    return blogService.getBlog();
  }
}

As you can see in the code, all web application settings are set as plain Java code inside the constructor. Most of these settings I used for development, so I’m skipping their meaning. You can learn more by looking at the ApplicationSettings javadoc. The main code we care about is in line 14, and it is where we are setting what component is going to respond as the home page (the main page of our application), which is just a reference to the Index class, which is our home page.

Home Page

Any Wicket page component needs to extend WebPage, so all of our pages will be a subclass. But, to make every page look the same, I’m defining an abstract base class that extends WebPage, and every page for my app will extend this class. BasePage is a very basic class that adds common components to the page:

package org.javageek.wicket;

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

public abstract class BasePage extends WebPage {
public BasePage() {
Blog blog = getBlog();
add(new Label(“blogName”, blog.getName()));
add(new Label(“blogDescription”, blog.getDescription()));
}

public Blog getBlog() {
return BlogApplication.instance().getBlog();
}
}

This is where the fun starts. As you can see, I just added two Label components, and each one has an id string, and content. Wicket defines a Model for every component, but it also offers convenience methods like the one I used for the labels. Wicket will wrap the string I’m sending as parameter inside a Model object so I don’t have to worry for very simple static cases like labels. After the page class is instantiated, the label components will be available inside the HTML for rendering, wherever I use their respective ids.

This is how the BasePage HTML looks like:

<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:wicket=”http://wicket.sourceforge.net/”
xml:lang=”en”
lang=”en”>
<wicket:head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″/>
<title wicket:id=”pageTitle”>[Blog Entry Title]</title>
<link rel=”stylesheet” href=”screen.css” type=”text/css” />
</wicket:head>

<body>
<div id=”container”>
<h1><span wicket:id=”blogName”>[Blog Name]</span></h1>
<h2><span wicket:id=”blogDescription”>[Blog Description]</span></h2>
<wicket:child/>
</div>
</body>
</html>

I made the BasePage abstract, so you can’t set it as a page and instead you need to subclass it. If you look closely at the body, there’s a <wicket:child/> tag, that will be replaced with the BasePage subclass’ view. Because we will subclass BasePage, this HTML will serve the purpose of a page template.

Wicket works by parsing the HTML and replacing any tag that has the wicket:id attribute with the content from the component’s model, based on the id of the component.

Our main page class, Index, subclasses BasePage and it’s where all the logic for displaying the list of the 3 most recent blog entries (in reverse date order) resides. For each blog entry we need to display title, excerpt (if present, with a “read more” link) or full body text, and the date it was posted.

The code for Index is:

package org.javageek.wicket;

import java.text.DateFormat;
import java.util.List;

import wicket.PageParameters;
import wicket.markup.html.basic.Label;
import wicket.markup.html.link.BookmarkablePageLink;
import wicket.markup.html.list.ListItem;
import wicket.markup.html.list.ListView;
import wicket.model.IModel;
import wicket.model.LoadableDetachableModel;
import wicket.util.string.Strings;
import domain.BlogEntry;

public class Index extends BasePage {
public Index() {
IModel entriesModel = new LoadableDetachableModel() {
@Override protected Object load() {
return getBlog().getBlogEntries();
}
};
add(new ListView(“blogEntries”, entriesModel) {
@Override protected IModel getListItemModel(IModel model, int index) {
List entries = (List) model.getObject(this);
BlogEntry current = (BlogEntry) entries.get(index);
return new BlogEntryModel(current);
}

@Override protected void populateItem(ListItem item) {
final BlogEntry entry = (BlogEntry) item.getModelObject();
final String excerpt = entry.getExcerpt();
final boolean hasExcerpt = !Strings.isEmpty(excerpt);
item.add(new Label(“entryTitle”, entry.getTitle()));
PageParameters params = new PageParameters();
params.put(“id”, entry.getId());
item.add(new BookmarkablePageLink(“viewBlogEntry”, ViewBlogEntry.class, params) {
                    @Override public boolean isVisible() {
                        return hasExcerpt;
                    }
                });

if (hasExcerpt) {
item.add(new Label(“entryBody”, entry.getExcerpt()).setEscapeModelStrings(false));
} else {
item.add(new Label(“entryBody”, entry.getBody()).setEscapeModelStrings(false));
}

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, getBlog().getLocale());
item.add(new Label(“entryDate”, df.format(entry.getDate())));
}
});
add(new Label(“pageTitle”, getBlog().getName()));
}
}

And this is what the whole HTML file for Index looks like:

<wicket:extend>
<div class=”blogEntry” wicket:id=”blogEntries”>
<h3 wicket:id=”entryTitle”>[Blog Entry Title]</h3>
<div wicket:id=”entryBody”>[Blog Entry Body]</div>
<p><a href=”#” wicket:id=”viewBlogEntry”>Read more</a></p>
<p>Posted on <span wicket:id=”entryDate”>[Blog Entry Date]</span></p>
</div>
</wicket:extend>

As you can see, I just created a web page using mostly Java, with only a very tiny html code that tells wicket where and how to render components. Also take note that the wicket:id attribute can be assigned to almost any HTML tag. Now, I won’t go into too much detail about how Wicket’s model work right now (I have to save something for a later post, don’t I?), but let’s just say that Wicket offers model separation, from the domain objects, to the wicket model objects by means of a couple of interfaces, like IModel.

An interesting thing that I will point out is that the “Read more” link is conditionally displayed by overriding the isVisible method of a BookmarkablePageLink (as shown in bold), and not inside the html (or jsp) as people are usually accustomed to do with other frameworks. This covers our main page, now let’s see how the other pages are done.

Blog detail Page

This page is actually very simple, with one exception. Here’s the code:

package org.javageek.wicket;

import java.text.DateFormat;

import wicket.PageParameters;
import wicket.markup.html.basic.Label;
import domain.Blog;
import domain.BlogEntry;

public class ViewBlogEntry extends BasePage {
public ViewBlogEntry(PageParameters parameters) {
super();
Blog blog = getBlog();
BlogEntry entry = blog.getBlogEntry(parameters.getString(“id”));
if(null == entry) {
redirectTo(new PageNotFound());
} else {
add(new Label(“entryTitle”, entry.getTitle()));
add(new Label(“entryBody”, entry.getBody()).setEscapeModelStrings(false));

add(new Label(“pageTitle”, entry.getTitle() + ” : ” + blog.getName()));

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, getBlog().getLocale());
add(new Label(“entryDate”, df.format(entry.getDate())));
}
}
}

and here’s the html:

<wicket:extend>
<div class=”blogEntry”>
<h3 wicket:id=”entryTitle”>[Blog Entry Title]</h3>
<div wicket:id=”entryBody”>[Blog Entry Body]</div>
<p>Posted on <span wicket:id=”entryDate”>[Blog Entry Date]</span></p>
</div>
</wicket:extend>

One thing to note with this page is that I’m overriding a constructor from WebPage that provides me with the page parameters as sent in the GET or POST request, conveniently wrapped as a Map object. Also, if any of these parameters (in our case an invalid entry id) produce a null entry (not found), I redirect the user to the PageNotFound class.

This is the code for the PageNotFound class, and basically it just sets the response status to 404:

package org.javageek.wicket;

import wicket.markup.html.basic.Label;
import wicket.protocol.http.WebResponse;

public class PageNotFound extends BasePage {
public PageNotFound() {
add(new Label(“pageTitle”, BlogApplication.instance().getBlog().getName()));
}

@Override protected void configureResponse() {
WebResponse wr= getWebRequestCycle().getWebResponse();
wr.getHttpServletResponse().setStatus(404);
}
}

(As a side note, It took me a while to get the 404 page to work, and I had to ask for help. Fortunately, the people from Wicket are very accesible and they have an irc channel at freenode, ##wicket, where they usually hang out. They also pointed out that this is much easier to do in Wicket 1.2, as you can throw an Exception instead of using the redirectTo method, which has a couple of quirks.)

And that’s it. I just created a web application using Wicket.

Summary

Wicket, in my opinion, focuses the development efforts in the right place, inside plain Java code, and leaves the graphical presentation where it should be, inside html. At first you might find a little hard to grasp this paradigm shift, as so many developers are being ‘forced’ to rely on jstl and jsp scriptlets to accomplish logic programming for a page with all the other frameworks. But once you get used to this, I’m sure wicket will provide really fast development times.

I am making the source available (under the Apache 2.0 License) if you want to check the code, although I posted everything except for the domain part on this article. You can use it as an introduction to Wicket, if you like. I hope you find something here useful.

Also, I want to thank Igor Vaynberg for his help with the source code, in particular the Model parts.

33 thoughts on “Comparing Web Frameworks: Wicket

  1. I’m not sure I understand your comment. Do you think Java web development takes forever because it took me one month to write the article, or because of ‘all’ the code you have to write?

    I have to say that writing the example code took me 2 days, from start to finish, working mostly after hours. And it was the first time I actually got into learning Wicket (i.e. no prior knowledge).

    So, why do you think creating web applications in Java take forever?

  2. I should disclose that I’m biased as originator of Wicket. But, yeah, I don’t get that comment either.

    It could be that this is coming from the VB crowd. Wicket is targeted at complex, stateful UIs and so is intended to be highly extensible and powerful. Since we don’t have the resources that JSF has (millions of dollars… or, in fact, even beer money), something like drag-drop support in an IDE plugin has taken a back seat (although there is a start on a Wicket plugin and I think that vision will eventually happen).

    Ironically, our limited resources have actually made for a stronger base framework because we cannot rely on tooling solutions to make things easy. Wicket is just plain Java. I think that limitation works out pretty well because it’s simple and leverages what you already know about a variety of technologies: The Wicket Vision Statement

  3. I am having a hard time seeing the justification in this. So what if you have to have loops in a JSP page to construct the visual representation of a collection of items. The whole point of the view is just that, to construct the view.

    I am trying to see how this format saves any time. This is like reverse polish notation to me. While it might be technically effective, it doesn’t appear to be readable or developer friendly. Does this look like self documenting code to you?

    I am trying to understand why you have to override so much rather than setting properties or event handlers if in fact this is an event driven framework. If the page or a page fragment defines its structure, why isn’t that structure passed to my Java code as a pre-instantiated model tree/tree fragment that I can then set properties thereof?

    On the Index page, instead of working with my domain objects directly, it appears you have to constantly retrieve and cast domain objects from the item model object. Why should I have to do this? For example, in the Index.populateItem method, why is that method not receiving an object tree that represents the elements that were defined in the template and then I fill in those instantiated elements with the appropriate data and set their properties or not accordingly. The code you have shown demonstrates that the developer has to know the elements that are defined in the template page and instantiate them. This is totally RPN.

    This doesn’t appear to be as productive as JSF/Facelets. I’m open to more examples but this isn’t a convincing case.

  4. Remember that the key words here are ‘separation of concern’. Sure, I can create loops in JSP, but that means I have to use JSP. With Wicket, you can leave the HTML creation to web designers who can do their magic in styling and polishing of a page.

    As for the overriding part, well, this is Java for you. In close-to-ideal-object-oriented frameworks, methods should be overriden, classes subclassed, etc.

    Regarding the Index.populateItem method, you misread that one. I’m actually creating an anonymous inner class of ListView which overrides populateItem. That could’ve been an external class, but I wanted to include it inside to make it ‘more readable’ in the sense that all the code is there and not on another file. The ListView is an object tree that is added to the Index class.

    The code you have shown demonstrates that the developer has to know the elements that are defined in the template page and instantiate them.

    Well, separation of concern doesn’t mean that the right hand doesn’t knows what the left hand does. It means that both hands can work in parallel

  5. I think you’re still missing the forest for the trees. I have illuminated some of this on the TSS article that points to this blog.

    I think the forest part is that separating out the /behavior/ into Java gives you incredible leverage that you cannot get by intertwining behavior and markup. To really see this, you have to play around with Wicket for a while I think. You can actually do some extremely sophisticated things with Wicket. Some of the UIs I’ve seen in Wicket are kindof jaw-dropping when you imagine what it would take to do the same thing in JSP. Comparing a couple of read-only, or even editable lists really does not get to the heart of what makes Wicket better. You have to construct something more complex to see it. Try making a tree of panels, each of which edits a list. This is not actually all that much code in Wicket. But try doing that in a JSP page!

    As far as the listener methods go, Wicket is fully extensible in its listener methods, but actually hides quite a bit of this in its class hierarchy. You don’t directly override the form submit listener for example because that is just an implementation details of “formness”. Instead you override methods of Form to respond to more abstract concepts.

    As far as model typing goes, this is coming in Wicket 2.0 when we introduce generics into Wicket models later this year (not much later, actually… Wicket 1.3 is going to be a very very quick cycle since we will only make one change in it… and then 2.0 will be immediately after that. if i had to guess, i’d guess that generic models ought to be here by June or so)

  6. Also, the markup IS passed into your component and you can do some intentionally limited things to it (like changing the tag a component is attached to before it renders). The reason this is not obvious at first glance is that we’ve gone to great extents to expose this only where it’s really necessary. If you implement some custom component, you may get down to the level of markup manipulation. However, 99.9% of the time you don’t need to do this in Wicket to get the effect you want.

  7. Also, the markup IS passed into your component and you can do some intentionally limited things to it (like changing the tag a component is attached to before it renders). The reason this is not obvious at first glance is that we’ve gone to great extents to expose this only where it’s really necessary. If you implement some custom component, you may get down to the level of markup manipulation. However, 99.9% of the time you don’t need to do this in Wicket to get the effect you want.

  8. Wicket as far as I am concerned is the way forward for web development in Java. A lot of creativity involved though especially with the loops but It makes Web Development so much fun. The only guys that will have problem with Wicket are those guys coming from a PHP background or JSP background with no knowledge of some Swing

  9. I have a feeling that there is still a strong need to “justify” the object orientation of Wicket. I have developed the Blogs application using the power of the object orientation. In this application, there is no specific view code (or some, but only for determining the context). It is based on generic components that have more knowledge of the domain model than Wicket predefined components. However, developing those generic components from the Wicket components was not difficult at all. And that is the power of Wicket. If you are interesetd, a zip file is ready to be sent.

  10. “focuses the development efforts in the right place, inside plain Java code” !!
    This was the winning ticket for me. The framework is truly amazing. I used ever dang framework in the book and can say that I’m most impressed with this one.

  11. 1) What I do not like looking at the Wicket code, is the need to register HTML elements:

       add(new Label("blogName" ...
    

    I think there should be a default behaviour, where I can register an object with a page and all properties of that object are accessible in the HTML. This would reduce the amount of code for forms with many fields/labels tremendously.

    2) I really hate struts for its tag library with its quirks populating drop-down boxes etc. but I do not understand the necessity to wrap everything in IModel and the like

    3) “Try making a tree of panels, each of which edits a list. This is not actually all that much code in Wicket. But try doing that in a JSP page!” Show me.

    4) I really would like to know more about the advantage/disadvantages w.r.t. Tapestry.

  12. < I am trying to see how this format saves any time.>>

    Suppose you have lots of different pages, many of which have a section that displays complex data in a complex but similar way. If you achieve this display by nesting standard tags you have to repeat this complex nesting of standard tags in each of those pages. You could create a custom tag, but that’s a lot of hard work to write and configure — and I don’t find the code for custom tags to be very readable.

    With JSP, you have to do a lot of work to connect your display logic with your model data; this was one of the motivations for the complex Struts framework. A component-oriented framework such as ASP.NET or JSF makes it easier to populate your display components with data and process updates, but the cost is even greater difficulty in creating, configuring and re-using your own custom display components. So instead of creating custom components you stick with the standard components and repeat the same nesting and configuration of them on page after page.

    With Wicket, you have a component-oriented framework in which it is _easy_ to create, configure and re-use customized display components. That’s because your components are instantiated, nested and configured using a full-powered object-oriented language, rather than having to do it in some primitive mark-up language.

  13. Great article with only one minor annoyance… I enjoyed the foreplay but where is the consummation?

    After reading this article I wanted to see the final webapp running (without having to download the src). I couldn’t find such a link? Any chance of putting a working example up somewhere?

  14. I think what’s really missing from Wicket are default renderers so you don’t have to touch html unless you want to customize. And really the only way to have default renderers is if Wicket also integrates layout managers.

    Take a look at qooxdoo.org or guiseframework.com for how to design a modern, productive framework.

  15. Based on what I have seen so far, Wicket appears to be the second best web framework. The best and the simplest framework has to be ZK (www.zkoss.org). Tapestry is probably third on the list. I hate bloatware like Struts & JSF.

  16. Please add a download link to the source.

    I tried to run this, but as I’ve never used Wicket before, I didn’t get the model code correct, like the BlogEntryModel.

    Thanks!

  17. Dude, talk about reviving a zombie :-) Anyway, I missed that article on TSS, but gosh did the author there not get the point.

  18. This is  really a good post. .  I was searching for all of these framework on internet but i got it from only one place i.e from here and with  the proper examples. thanks for sharing.. well done.

Leave a Reply