I dunno if this is a valid question for this site, but I was wondering if someone experienced with the ContentNegotiatingViewResolver could look this over and let me know if I set it up correctly and well as help me send 404 messages.
What I'd like to do is make all urls with no extension default to the HTML representation (which is freemarker views in my case). I'd like to accept urls with ".json" appended to them to render json instead. This appears to work in firefox, ie and chrome. I'm guessing it works in other browsers? I made sure to disable the accept header because it's an evil feature that doesn't really work like the documentation says it does.
I have tried to access urls with ".stuff", just to see what happens, and with my configuration, a blank screen happens. Is this acceptable? Is there any way I can send a 404 error?
Is there anything else that I may have not configured properly?
<bean id="contentNegotiatingViewResolver"
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1"/>
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="text/html" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="useNotAcceptableStatusCode" value="true" />
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="contentType" value="application/json" />
</bean>
</list>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="contentType" value="text/html" />
<property name="order" value="2"/>
<property name="cache" value="true"/>
<property name="prefix" value=""/>
<property name="suffix" value=".ftl"/>
<property name="exposeSpringMacroHelpers" value="true"/>
</bean>
</list>
</property>
</bean>
In this case, when a URL is requested, Spring MVC will use “ ContentNegotiatingViewResolver ” (order=1) to return a suitable view (based on file extension declared in “mediaTypes” property), if not match, then use “ InternalResourceViewResolver ” (order=2) to return a default JSP page.
You can configure a content negotiation strategy centrally once and it will apply wherever different formats (media types) need to be determined. Spring supports a couple of conventions for selecting the format required: URL suffixes and/or a URL parameter. These work alongside the use of Accept headers.
Spring MVC has long supported multiple view resolvers, and goes to each in turn to find a view. Although the order that view resolvers are consulted can be specified, Spring MVC always picks the first view offered.
Generally, there are three options to determine the media type of a request: (Deprecated) Using URL suffixes (extensions) in the request (eg .xml/.json) By default, this is the order in which the Spring content negotiation manager will try to use these three strategies.
Because you have defaultContentType set, the negotiation always ends up finding a matching content type delivered by the freemarker view. A quote from the javadoc of ContentNegotiatingViewResolver:
You can also set the setDefaultContentType directly, which will be returned when the other mechanisms (Accept header, file extension or parameter) do not result in a match.
With this setting, file extension .stuff matches contentType text/html.
Then, with useNotAcceptableStatusCode:
406 (Not Acceptable) status code will be returned if no match is found.
I just tried this (with the settings of another REST service app) and saw Chrome showing the message: The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With