About Me

My photo
I'm project manager of a software development team at www.researchspace.com. I've been developing bioinformatics software for the last 9 years or so, and I'm hoping to share some of the experience and knowledge I've gained with Eclipse RCP, Java web app development and software development in general on these blogs.

Thursday, 31 January 2013

Updating from Spring 3.0 to 3.2

We recently updated our Spring libraries from 3.0.5 to 3.2. It's the first time we have updated Spring libraries in our webapp; we use Spring heavily and were a little nervous if everything would still work. But encouraged by their commitment to backwards compatibility we went ahead... all unit and database tests continued to pass.. great!
Running the application however had a few problems. We had been using  a ContentNegotiatingViewResolver to return a PDF view of certain webpages when the URL ends in ',pdf'. After updating, all webpages were trying to return pdf content, even without the suffix, or we would get a ClassCastException ('String cannot be converted to Media Type').

Content negotiation is not trivial to sort out, and it seems in 3.2 Spring have tried to make it more flexible, configurable and reusable, by introducing  ContentNegotiationStrategy implementations which resolve views using different policies. This is documented here, but at least to me the documentation is a bit cryptic and hard to understand.
Here is how we fixed this:






Note that there are two strategies:PathExtensionContentNegotiationStrategy and HeaderContentNegotiationStrategy. These are evaluated in the order they appear in the list.
  1. First of all, if the request URL has a suffix, the path extension strategy will try to find a view resolver that can deal with that suffix, based on the media type mappings supplied to the constructor. If a match is found, no more strategies are evaluated
  2. If there was no suffix, or there is no view, the HeaderContentNegotiationStrategy  will examine the request headers, and match up a view.
  3. Views are then evaluated to a 'best match' as in earlier versions of Spring.
 In this case, if there is no file suffix, the normal request header will result in a Jstl view being generated.
I'm sure people have different strategies for handling content negotiation; upgrading to 3.2 did break our current web app but hopefully this solution will help others.