0

我正在使用 JSONP 在 Spring MVC 中调用控制器服务。我有一个自定义过滤器,它返回包含在回调中的结果。我使用了这个例子,http://jpgmr.wordpress.com/2010/07/28/tutorial-implementing-a-servlet-filter-for-jsonp-callback-with-springs-delegatingfilterproxy/。我也在使用 ContentNegotiatingViewResolver 但我的结果在回调中不断返回 XML。为什么会一直这样?

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>
4

4 回答 4

1

我的猜测是您的控制器方法正在使用@ResponseBody,并且您返回的模型对象标有 Jaxb2 注释(特别是 @XmlRootElement)。

我遇到了和你一样的问题。问题是,@ResponseBody 绕过了 ContentNegotiatingViewResolver。您可以通过向 ContentNegotiatingViewResolver 的方法(如“resolveViewName”)添加一些断点来确认这一点,并查看它是否真的被命中(它不会)。

我正在使用的当前工作是实际声明一个 json 视图并专门使用它。

您必须在 xml 中添加类似的内容:

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

然后,您也可以将列表项更改为如下所示:

<beans:ref bean="jsonView" />

然后,您的控制器方法将返回一个 ModelAndView,如下所示:

@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);
}

或者,您可以将视图作为字符串返回,并在方法签名中添加声明 ModelMap:

@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";
}

希望这可以帮助。

(注意:从内存中输入,因此可能会出现语法错误等)

我还没有找到更优雅的解决这个问题的方法,但是如果我找到了,我会在这里发布。

编辑:

尝试删除@ResponseBody。如果这样做,MessageConverters 将不会被激活,而 ContentNegotiatingViewResolver 将被触发。此时,它应该是确定视图的扩展(基于您的设置)。

除了删除 @ResponseBody 之外,您不必更改任何内容,返回类型可以保持不变。

于 2011-03-23T15:34:47.483 回答
0

我的临时解决方案是使用一个 JSON 解析器,它接受 XML 并将其暂时转换为 JSON。是的,将其解析为 XML 然后返回 JSON 很糟糕,但现在这将不得不工作。

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());
于 2011-03-23T16:05:04.887 回答
0

很高兴看到我的博客文章是你的灵感!:-D

您是否已将 Jackson 映射器 API 添加到您的依赖项中?创建 Spring MVC 应用程序时,默认情况下它不会存在。您必须自己添加它,然后它应该编组对 JSON 的响应。

于 2011-03-23T11:02:00.240 回答
0

检查您的请求的 Accept 标头。

于 2011-03-23T08:04:40.563 回答