Skip to: Site menu | Main content

Render a Wicket page to a string for HTML email

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.

3 Responses to “Render a Wicket page to a string for HTML email”

  1. Jörn Zaefferer Says:

    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.

  2. Ro Says:

    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.

  3. Jörn Zaefferer Says:

    Got it working by replacing requestCycle.request() with requestCycle.getProcessor().respond(requestCycle);

    Thanks for sharing!

Leave a Reply