Sunday, October 22, 2006

Wicket + Sitemesh = feces nocturnus

Everything was going so well... I could make Wicket say "hello world" and get Sitemesh to decorate the page into my style, and then I thought, "now I should try a simple form!" That way, I could fail fast if form handling wasn't going to work, and I could learn what the "Wicket way" is for handling form submission and validation.

Since the first thing I want to replace on morons.org is article submission, I decided to come up with a simple article form. After one tiny hitch (if you include a wicket:id tag in the HTML, you must define a corresponding element in your WebPage; this is a good thing because it means you can't forget to define everything properly) I got the form displayed.

Then disaster struck when I hit the submit button! Not only did the processed form not render, but only a small amount of the decorator showed up. What the hell? Not only that, but hitting the Reload button made the page display as-expected!

After much digging, it came to light that there was a problem with the Content Length. The actual number of bytes in the HTTP Response buffer did not match the number of bytes it claimed to hold, by a difference of about 9KB. As it happened, the size it claimed to have roughly matched the size of the rendered Wicket form... and the difference was about the size of the decorator. I posted to the Wicket Users mailing list and the Sitemesh forum and went to bed, wondering if I could use my SevenBitFilter (which turns literal UTF8 characters into their HTML entity equivalents so the whole page is 7-bit ASCII) to work around the problem, since the SevenBitFilter would reset the Content Length (because it changes the length in most cases).

In the morning, I was pleased to find the answer in my email. Wicket uses different Render Strategies to deliver a rendered page to the end user. The default strategy is to render to a buffer stored in the user's session, then send the client a redirect to another URL; when the redirect is completed, Wicket then dumps the contents of that buffer. The reason for doing this is apparently to prevent the user from double-posting-- clicking "submit" twice in a row.

For some reason, Sitemesh doesn't like that strategy, though I'm at a bit of a loss to understand why it would notice or care. Probably there is some characteristic particular to a redirect that upsets it.

The solution is to change the render strategy for the application by calling getRequestCycleSettings().setRenderStrategy(IRequestCycleSettings.ONE_PASS_RENDER) from the WebApplication's init() method. This does mean that I'll have to handle double-posts myself, but I was planning to do that anyway, so it's not really a setback.

I'm starting to build up a set of settings that I like for my applications, so I may factor out my own WebApplication parent class (a subclass of WebApplication but a parent class to my other applications) that defines those settings by default next.

I'm also thinking about coding up a servlet filter that dumps the state of the Request and Response objects that can be inserted before and/or after any other servlet filter. Then maybe I could see what it was that caused Sitemesh its intestinal discomfort and provide a more detailed bug report. Unfortunately, development on Sitemesh seems to have all but ground to a halt 14 months ago despite promise of an impending new release. That's a bit worrysome.

Labels:


Comments:
This post has been removed by the author.
 
Just to update the Wicket Wiki link - since the move to Apache, it's at http://cwiki.apache.org/WICKET/render-strategies.html

3:49 AM
 
Hi There

Could u please send the sample code for integrating wicket + sitemesh to my email kumaran.thava@gmail.com pls?

Regards
Kumaran
 
No, since I don't have it anymore, and you shouldn't be doing that anyway. Just use Wicket's own markup inheritance instead.
 
Post a Comment





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]