开发者

JSONP and Custom Filter Returning XML instead in Spring MVC

开发者 https://www.devze.com 2023-02-19 15:45 出处:网络
I am using JSONP to call a controller service in Spring MVC.I have a custom filter that returns the result wrapped in the callback.I used this example, http://jpgmr.wordpress.com/2010/07/28/tutorial-i

I am using JSONP to call a controller service in Spring MVC. I have a custom filter that returns the result wrapped in the callback. I used this example, http://jpgmr.wordpress.com/2010/07/28/tutorial-implementing-a-servlet-filter-for-jsonp-callback-with-springs-delegatingfilterproxy/. I am also using ContentNegotiatingViewResolver but my result keeps returning XML in the callback. Why would it keep doing that?

jQuery1509349652162468509_1300839533498(<?xml version="1.0" encoding="UTF-8" standalone="yes"?><followResponse><id>0</id></followResponse>);

servlet-context.xml

<beans:bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <beans:property name="order" value="1"/>
        <beans:property name="mediaTypes">
            <beans:map>
                <beans:entry key="json" value="application/x-json"/>
                <beans:entry key="json" value="text/json"/>
                <beans:entry key="json" value="text/x-json"/>
                <beans:entry key="json" value="application/json"/>
                <beans:entry key="xml" value="text/xml"/>
                <beans:entry key="xml" value="application/xml"/>
            </beans:map>
        </beans:property>
        <beans:开发者_如何转开发property name="defaultViews">
            <beans:list>
                <beans:bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
                <beans:bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <beans:property name="marshaller">
                        <beans:bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
                    </beans:property>
                 </beans:bean>
            </beans:list>
        </beans:property>
    </beans:bean>


My guess is that you're controller method is using @ResponseBody and that the model objects your're returning are marked up with Jaxb2 annotations (specifically @XmlRootElement).

I had the same issue that you are having. The problem is, @ResponseBody bypasses the ContentNegotiatingViewResolver. You can confirm this by adding some break points to methods of the ContentNegotiatingViewResolver like "resolveViewName" and see if it actually gets hit (it won't).

The current work around I am using is to actually declare a json view and specifically use it.

You would have to add something like this to your xml:

<bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>

You can then change your list item to look something like this as well:

<beans:ref bean="jsonView" />

Your controller method would then return a ModelAndView like so:

@RequestMapping(value = "/{username}/get.json", method = RequestMethod.GET)
public ModelAndView getUser(@PathVariable String username) {
    User user = service.getUser(username);
    return new ModelAndView("jsonView", "user", user);
}

Or, you can just return the view as a string, and add declare a ModelMap in your method signature:

@RequestMapping(value = "/{username}/get.json", method = RequestMethod.GET)
public String getUser(@PathVariable String username, ModelMap model) {
    User user = service.getUser(username);
    model.addAttribute("user", user);
    return "jsonView";
}

Hope this helps.

(Note: typing this out from memory, so there's potential for syntax errors, etc)

I haven't found a more elegant solution to this problem yet, but if I do, I'll post it here.

EDIT:

Try removing @ResponseBody. If you do this, the MessageConverters will not be activated, and the ContentNegotiatingViewResolver will be triggered. At this point, it should be the extension that determines the view (based on your setup).

You shouldn't have to change anything other than removing @ResponseBody, the return type can stay the same.


Check the Accept header of your request.


Nice to see my blog post was your inspiration! :-D

Have you added the Jackson mapper API to your dependencies? It won't be there by default when creating a Spring MVC app. You have to add it yourself and then it should marshall the response to JSON.


My temp solution was to use a JSON parser that takes XML and converts it to JSON for the time being. Yea it sucks to have it parsed to XML then back to JSON, but for now this is going to have to work.

String xml = new String(wrapper.getData());

            if(!StringUtils.isEmpty(xml))
            {
                XMLSerializer xmlSerializer = new XMLSerializer(); 
                JSON json = xmlSerializer.read( xml );  
                out.write(json.toString().getBytes());
            }

            out.write(new String(");").getBytes());
0

精彩评论

暂无评论...
验证码 换一张
取 消