views:

978

answers:

1

I was reading the Spring 3.0 Documentation and Blog Posts (followups) on how to create REST style services with Spring MVC but I can't find any working example on how to use the ContentNegotiatingViewResolver. I have a test controller like this

@Controller
public class IndexController implements Serializable
{
    @RequestMapping("/index")
    public ModelAndView index()
    {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("index");
        return mav;
    }   
}

and tried to use something like this

<bean
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
        <map>
            <entry key="html" value="text/html" />
            <entry key="xml" value="text/xml" />
            <!--
                <entry key="json" value="application/json"/>
            -->
        </map>
    </property>
    <property name="defaultContentType"><value>text/html</value></property>
    <property name="defaultViews">
        <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
            <property name="marshaller">
                <bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
            </property>
        </bean>
    </property>
    <property name="viewResolvers">
        <list>
            <bean
                class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/views/pages/" />
                <property name="suffix" value=".jsp" />
            </bean>
        </list>
    </property>
</bean>

trying to resolve the views according to the extension in the URL (I want to support html, .xml and .json). The .html view works (showing the correct JSP view, too) but nothing else I tried for getting JSON and XML up and running seems to work (setting the defaultViews property was just one of the things I tried). There doesn't seem to be that much reading material either. Does anybody have experience or examples?

+2  A: 

I believe you're problem is that the content-type of XML is not text/xml, it's application/xml. You'll find that MarshallingView will not accept a content type of text/xml.

What ContentNegotiatingViewResolver does is consult each of its views, asking them if they'll accept the content type that was resolved from the request. For each content type you want to support, you need a view with a matching contentType property.

You can either change the content type in the mediaTypes property, or you can override contentType property of MarshallingView to be text/xml.

skaffman
Thanks, the content-type was wrong indeed, but now I get an exception saying "Unable to locate object to be marshalled in model {}". Is the XML Marshaller configured correctly (I wanted to configure XStream to generate JSON, too).
Daff
@Daff It's because your model is empty
axtavt
Indeed, you need to set up your model so that the `MarshallingView` knows what to do with this. This, however, is a whole different question, so please accept this one as done, and move on to the next.
skaffman
Got it... I think I can work with that and setup the other views, too, now that I know how it works.
Daff