What I hate about Wicket Framework

This post describes my opinion about Wicket framework.

Wicket is a component-based Java web framework from Apache that is gaining some popularity. Like most component-based web frameworks, Wicket is harder to learn than controller-to-view frameworks (Request-based) like Grails, Stripes, Servlets/JSP, Rails etc., but it offers more features and is more focused on the state of HTML elements instead of the state of HTTP requests. (Update 7-July-2010: to be clear, I don’t think controller-to-view frameworks are better, I just think they are easier to learn. But when you need to develop a WebApp, I think component based frameworks make the development easier.)

It’s not that I hate Wicket, but there are some features that I don’t like:

Heavily based on sessions.

Although Wicket does offer a few stateless components and session-less features, it is heavily based on sessions. Without session, state-fullness is difficult. Sessions have two drawbacks: timeouts and memory consumption.
A timeout occurs when a user doesn’t respond within (usually) 30 minutes. When that happens, the state of the page the user visited is lost. There are some Ajax hacks around this, but they are cumbersome. An option is to increase the timeout, but then you will be limited by memory consumption of sessions.
Some argue that memory is cheap, but that depends on your situation. If you’re building some in-house Website/webapp for a  company running its own servers than memory is indeed cheap. If you are a student or a freelance developer that is deploying the website on some leased VPS (Virtual Private Server) or a dedicated server, than the memory usage can increase the costs a lot.
What I like is the solution of Microsofts ASP.NET framework. It uses viewstates instead of sessions, which stores state in hidden html elements that are submitted back to the server when the user triggers an event, by using Javascript. This approach also has some drawbacks, but it doesn’t depend on sessions.

Wicket team had plans of implementing “client-side models for zero-state scalability”, but unfortunately they dropped it.

High learning curve

Component-based frameworks (pull MVC) are more difficult to learn than controller-to-view based frameworks (push MVC). This makes documentation more important, but the recommended book Wicket in Action doesn’t provide much inside in about how Wicket exactly works. This makes it difficult to do a bit more than standard stuff, when after you have read it.

Wicket URLs

I hate it when URLs reveal the usage of a framework. Wicket has Url Coding Strategies to fix this, but when using statefull pages, these urls often reveal the Wicket framework, this because Wicket uses the url to track a version of a web page. For example, you might get URLs like:
http://example.com/product/abc/.1.2 and when you click on some component on that page that will let you stay on the page but which some updated components, then you get http://example.com/product/abc/.1.3
The unwanted part is .1.3. It should stay http://example.com/product/abc all the time.

When clicking a component, there also often is an unwanted extra HTTP redirect before fetching the final HTML.

HTML is not that pure

A philosophy in Wicket is that HTML should strictly be separated from code and component properties, so that a web designer can make the HTML, and the programmer can just code Java. I hate the idea of making it easier for a web designer (highly subjective opinion), since I’m a programmer that makes the HTML/CSS myself, but I like the idea of separating it cleanly. But when using Wicket you will get a lot of tags like this in your HTML when you  need to repeat components:
<wicket:container>……</wicket:container>
So the HTML isn’t that pure.
If you don’t use that container element, than you easily get two nested divs where only one div is needed.

Update 11-July-2010: the commenter “anonymous coward” showed unwanted divs can be prevented by using setRenderBodyOnly. Other not-pure HTML can occur when Wicket Fragments are used, but this scenario doesn’t happen often.

Static component tree

It would be nice if you can create a tree of components dynamically, but in Wicket you have to define the tree structure statically in both the HTML layout and the Java code. It is possible to switch subtrees, but those subtrees have to be defined upfront.

Very verbose

Because of the clean separation of html and Java, and because it’s a component based framework, code will be more verbose than standard push MVC framework. A feature of Wicket that makes it even more verbose is the use of “models”. Model objects can be used by components to retrieve data, so that there is a clear distinction between data and data retrieval. This becomes clear when using repeating elements in HTML. Then you usually need to define LoadableDetachableModel anonymous classes that are nothing more than packed method calls to your DAOs (Data Access Objects) to retrieve data.

What I do like

This blog post is focused on what I don’t like, but to give you a short idea of what I do like:

——————–

Update 7 July 2010: changed “complexity” to “high learning curve”. And wrote more explicitly that I do favor component based frameworks over controller-to-view/request based frameworks, like the commenters below also do.

Update 11 July 2010: changed my opinion about “Not pure HTML” after the post of the commenter “anonymous coward”.

Wicket – Sending a 301 redirect

This post describes how to send a HTTP 301 redirect in the Java Wicket Framework.

HTTP redirect intro

There are two types of HTTP redirects:
-“HTTP 1.1 301 Moved Permanently”
-“HTTP 1.1 302 Found”, previously called “HTTP 1.1 302 Moved Temporarily”

A 301 indicates that the requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs.
Where a 302 indicates that the requested resource resides temporarily under a different URI.

For a normal web browser it doesn’t matter which type of redirect is send to the browser, because the result is the same: the user is redirect to a different URI. But for Search Engines (SE’s) it does (or might) matter, at least if you want the correct URL to be indexed. If you’re using a 301, than you’re telling SE’s that they should use the new URI. If you’re sending a 302 then you’re telling that they should use the old URI.

301 using Wicket

In Wicket, you can send a 301 using:

getRequestCycle().setRequestTarget(new RedirectRequestTarget("/path/to/legacyJspFile.jsp"));

302 using Wicket

The problem is that the redirect method always uses a 302. If you want to perform a 301, you can use this code, which overrides the respond method:

RedirectRequestTarget target = new RedirectRequestTarget(url) {
  @Override
  public void respond(RequestCycle requestCycle) {
    WebResponse response = (WebResponse) requestCycle.getResponse();
    response.reset();
    response.getHttpServletResponse().setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
    response.redirect(url);
  }
};
getRequestCycle().setRequestTarget(target);

This will cause the RedirectRequestTarget.respond(RequestCycle requestCycle) method to be called, which will get a WebResponse object using the requestCycle object, and it will call the WebResponse.redirect(String url) to set the redirect.

More info:

  • http://wicket.apache.org/docs/1.4/
  • http://www.w3.org/Protocols/rfc2616/rfc2616.txt
  • http://cwiki.apache.org/WICKET/how-to-redirect-to-an-external-non-wicket-page.html

Struts2 table annoyance

I was trying out a bit of Struts 2 just to test it out. An annoyance that quickly came up is that the HTML layout of forms are all table based. For example, if you want an input field for your name, then a column-based HTML table will be created automatically for that. The first column contains a HTML label, and the second the input field.

For example, the following Struts2 code:

<s:form action="HelloWorld">
    		<s:textfield name="name" label="Your name"/>
    		<s:submit/>
		</s:form>

will yield this HTML code:

<form id="HelloWorld" name="HelloWorld" onsubmit="return true;" action="/StrutsInAction/chapterTwo/HelloWorld.action" method="post">
	<table class="wwFormTable">
		<tr>
			<td class="tdLabel"><label for="HelloWorld_name" class="label">Your name:</label></td>
			<td><input type="text" name="name" value="" id="HelloWorld_name"/></td>
		</tr>
   		<tr>
			<td colspan="2"><div align="right"><input type="submit" id="HelloWorld_0" value="Submit"/></div></td>
		</tr>
	</table>
</form>

What if you want to work without HTML tables? Or what if you want to put a label on the first row and its input field on the second row, instead of using two columns? You can by using the “simple” theme instead of the default “xhtml” theme. Set it using:

<s:form action="HelloWorld" theme="simple">[/xml]
The generated HTML code will now be:
<form id="HelloWorld" name="HelloWorld" onsubmit="return true;" action="/StrutsInAction/chapterTwo/HelloWorld.action" method="post">
	<input type="text" name="name" value="" id="HelloWorld_name"/>
	<input type="submit" id="HelloWorld_0" value="Submit"/>
</form>

But…. using the simple theme, will drop validation, error reporting, ajax etc……

So if you don’t want those column based HTML tables but do want the default framework functionality (validation etc), you will have to make your own themes……

JSF doesn’t have this problem, there you could just write something like:

<h:form>
	<h:outputLabel for="name">Your name:</h:outputLabel>
	<h:inputText value="#{formAction.name}"/>

This is a bit more coding then using Struts 2, but it gives you the flexibility to place the outputLabel wherever you want, instead of being locked to two HTML columns.

More info:
http://struts.apache.org/2.x/docs/themes-and-templates.html
http://www.vitarara.org/cms/struts_2_cookbook/creating_a_theme