Easy Static Asset Expiration in J2EE

October 16, 2009

Just ran into a defect that came up because QA’s web browser had cached an old version of a JS file. I was hoping to find an easy way to configure caching for static assets in my webapp. Turns out that there’s a J2EE cache-filter that does it quite easily. Just add it to your pom or lib directory, then add a few filters and filter-mappings to your web.xml, and you’re good to go!

I configured 1 hr caching for JS and CSS, so they’ll be refreshed by the time I do a QA build. You could also set up your build script to make your cache settings environment-specific, so prod caches longer than QA. You can also use this to set longer caches on things like images (I set ’em to cache for 1 day), to increase performance.

xhtmlrenderer PDF Servlet Filter

August 12, 2008

I managed to get xhtmlrenderer working as a Servlet Filter, so that any HTML page you apply the filter to will be converted to PDF. Here are a few hints:

  • If you want to keep the XHTML in memory rather than writing it out to a file, then you’ll need an XML parser like Xerces to parse the XHTML into a DOM object before you can pass it to xhtmlrenderer. (iText has got to have some kind of XML parser it uses that you could probably use too, instead of including a separate library. I just didn’t take the time to figure it out.)
  • You’ll need something like a ByteArrayServletOutputStream to capture the JSP output in-memory so you can then convert it to PDF. Catalina has one.
  • If you have a table that spans multiple pages and you want to repeat the table header and footer on each page, use the custom CSS attribute “-fs-table-paginate: paginate;” on the table.
  • Be sure to pass xhtmlrenderer the URL of the page it’s rendering, so that it can access relative URLs to pull up external resources like images and CSS files.
  • I’m using JSPs as the templating solution, and I ran into some buffering issues where no content was written into the ServletOutputStream when I was applying the filter. A manual call to out.flush() at the end of the JSP works for now, but I’m looking for a better solution.