Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is My Spring-MVC ContentNegotiatingViewResolver setup correctly? How can I send 404 error for unsupported media types?

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>
like image 484
egervari Avatar asked Nov 23 '11 18:11

egervari


People also ask

What is contentnegotiatingviewresolver in Spring MVC?

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.

How do I configure content negotiation in spring?

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.

How does Spring MVC handle multiple view resolvers?

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.

How do I determine the media type of a spring request?

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.


1 Answers

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().

like image 103
Assen Kolov Avatar answered Oct 02 '22 21:10

Assen Kolov