Ok this is probably going to be a long response so buckle your seat belt
ContentNegotiatingViewResolver does not resolve views itself but rather delegates to other view resolvers, like your MappingJacksonJsonView, or your MarshallingView. There are 2 strategies for determining the correct representation:
1. Distinct URI - This is where your request ends in .json or .xml
2. Content Negotiation - The correct media type is read off of the Accept Header of the request.
Now when you configured your view resolvers you specified the Content-Type(Media type) along with your keys for example
<entry key="json" value="application/json" />
Here what you have done is opted to use the URI strategy above. This line in turn mapped the .json file extension to the Content-Type of "application/json" . So if a request comes in with a .json file extension the ContentNegotiatingViewResolver will go down the ViewResolver chain and return the first View it finds that supports that content type, which will turn out to be MappingJacksonJsonView.
The ViewResolver chain I just mentioned is the same viewResolvers property on the ContentNegotiatingViewResolver that you asked about. If it makes it through the entire list of ViewResolvers and does not find a match it will go through the views specified by the DefaultViews property. Default views are singleton views that can render an appropriate response regardless of the logical view name. Both MappingJacksonJsonView and MarshallingView would be good examples of this.
Following is an example:
Now because in your example you did not define <property name="viewResolvers"> the ContentNegotiatingViewResolver will automatically use any ViewResolver that it can find defined in the application context.
If you chose to not include the file extension .json or .xml then it would consult the Accept Header to find the correct resolution. This is problematic at times since browsers will submit with an an Accept header similar to the following
This is impossible to to change with HTML, which is why for browser based applications the URI pattern
is generally used. BTW this is also why your second example only returned XML (notice there is no json in that header, but more on that later)
Now lets talk about @ResponseBody-
When your method is annotated with @ResponseBody you are indicating that the return type should be written straight the the HTTP response body and not interpreted as a view name or placed in model. In order to facilitate this Spring converts your returned object to a response body by using a HttpMessageConverter.
Where did they come from? Spring registers several of these for you automatically including MappingJacksonHttpMessageConverter if Jackson is found on the classpath and Jaxb2RootElementHttpMessageConverter if JaxB is found on the class path.
Now unlike the ContentNegotiatingViewResolver file extensions don't help you here. All the resolution is made from the headers. If the Accept header of the request is set to "application/xml" (as would have been in your example), XML will be returned regardless of whether you put a .json on the end. To be clear and enforce correct mapping you should
make use of the consumes and produces properties of the @RequestMapping.
For example take this method that takes an xml or json message posted in and returns some sort of response -
What this will do for you is when spring is mapping the request to this handler method it will ensure that the Content-Type and Accept headers of the request must be either "application/xml" or "application/json" for this method to process the request.
Now say this endpoint is being posted in via some jquery/ajax from my jsp
. If I set my Content-Type to "application/json" and my Accept to "application/xml" this method will accept that request. It will assume that someOtherObject is json and will unmarshall it for me. It will do whatever it needs to do and use the Jaxb2RootElementHttpMessageConverter to write my instance of SomeObject as XML to the HTTP response.
To play with this more use this fire fox extension which allows you to set the headers:
Also note there is a jira for equalizing the abilities of @ResponseBody with what the ContentNegotiatingViewResolver can do (like URI based resolution) look for it coming up in Spring 3.2
Hope that helps.