Render a Wicket page to a string for HTML email
October 21st, 2008
Something that’s very desirable to do in Apache Wicket is create HTML emails using Wicket’s brilliant component-oriented markup.
I’ve been working on this problem on and off for ages — it’s tricky because of teh way that markup rendering is so deeply tied to the requestcycle, which in turn is deeply dependent on the httpservletrequest — with good reason, too. That’s where Wicket gets its autoconfiguring magic from!
So in order to use Wicket to create HTML emails, we need to fake the request/response cycle. I wrote this convenient method that renders a bookmarkable page (pageclass + pageparameters) to a string:
protected String renderPage(Class<? extends Page> pageClass, PageParameters pageParameters) {
//get the servlet context
WebApplication application = (WebApplication) WebApplication.get();
ServletContext context = application.getServletContext();
//fake a request/response cycle
MockHttpSession servletSession = new MockHttpSession(context);
servletSession.setTemporary(true);
MockHttpServletRequest servletRequest = new MockHttpServletRequest(
application, servletSession, context);
MockHttpServletResponse servletResponse = new MockHttpServletResponse(
servletRequest);
//initialize request and response
servletRequest.initialize();
servletResponse.initialize();
WebRequest webRequest = new WebRequest(servletRequest);
BufferedWebResponse webResponse = new BufferedWebResponse(servletResponse);
webResponse.setAjax(true);
WebRequestCycle requestCycle = new WebRequestCycle(
application, webRequest, webResponse);
requestCycle.setRequestTarget(new BookmarkablePageRequestTarget(pageClass, pageParameters));
try {
requestCycle.request();
log.warn("Response after request: "+webResponse.toString());
if (requestCycle.wasHandled() == false) {
requestCycle.setRequestTarget(new WebErrorCodeResponseTarget(
HttpServletResponse.SC_NOT_FOUND));
}
requestCycle.detach();
} finally {
requestCycle.getResponse().close();
}
return webResponse.toString();
}
One other thing that’s desirable to do is change all relative links in the email to absolute URLs — something that Wicket makes super-easy, if you know how. That will be the subject of my next post.
November 4th, 2008 at 9:25 am
Hi Dan,
thanks for the post, that seems to be exactly what I’m looking for.
Copying the code into my app, I got a compiler error on the line where the WebRequest is created. Using the constructor to ServletWebRequest helped.
Nonetheless, I get only an empty string back, no clue whats going wrong.
I’m using Wicket 1.3.5.
November 4th, 2008 at 10:09 am
We are also using Wicket in combination with Spring. Wouldn’t it be easier to use Spring + Velocity to generate HTML Emails?
http://www.theserverside.com/tt/blogs/showblog.tss?id=SpringVelocityEmail
Although I would prefer a solution that is more tied to Wicket, the Spring solution seems to be easier to grab and thus more maintainable IMHO.
I never tried it any of the above, but will have to in the next couple of months.
November 5th, 2008 at 3:27 am
Got it working by replacing requestCycle.request() with requestCycle.getProcessor().respond(requestCycle);
Thanks for sharing!