使用spring mvc返回JSON,chrome可以,firefox不行的问题定位

                                                       转载http://ks.netease.com/blog?id=4024 作者:李景

场景:

前端Post请求同一个url地址,在chrome浏览器上有正常返回json,而在firefox浏览器上却报500错误。

下面是controller层的写法:

其他类似的接口都可以正常使用,查看了其他接口的写法,区别在于多了一个header。

与其他接口唯一的区别就是少写了一个Accept=application/json。

这是为什么呢?通过查看源码以及对两个浏览器请求头的对比,终于找出问题的原因,下面一一道来。

看到后台有报错:

根据错误,大概可以看出是模板解析错误,怎么用ff请求的时候会使用xml进行解析呢?

应用是使用Freemarker进行页面渲染,配置如下:

 <bean            >        <property name="defaultContentType" value="application/json"/>        <property name="mediaTypes">            <map>                <entry key="html" value="text/html;charset=UTF-8"/>                <entry key="json" value="application/json;charset=UTF-8"/>                <entry key="xml" value="application/xml;charset=UTF-8"/>            </map>        </property>        <property name="viewResolvers">            <list>                <bean                        >                    <property name="cache" value="false"/>                    <property name="prefix" value=""/>                    <property name="suffix" value=".ftl"/>                    <property name="exposeSpringMacroHelpers" value="true"/>                    <property name="exposeRequestAttributes" value="true"/>                    <property name="exposeSessionAttributes" value="true"/>                    <property name="allowSessionOverride" value="true"/>                    <property name="contentType" value="text/html;charset=UTF-8"/>                </bean>            </list>        </property>        <property name="defaultViews">            <list>                <bean                        >                    <property name="objectMapper" ref="objectMapper"/>                    <property name="contentType" value="application/json;charset=UTF-8"/>                    <property name="modelKeys">                        <set>                            <value>msg</value>                            <value>res</value>                            <value>errmsg</value>                        </set>                    </property>                </bean>                <bean id="marshallingView"                      >                    <property name="marshaller" ref="xstreamMarshaller"></property><property name="modelKey" value="msg"></property>                   <property name="contentType" value="application/xml"/>                </bean>            </list>        </property>    </bean>

Freemarker有两种默认的返回结果,分别是json和xml。

最后返回的结果会由org.springframework.web.servlet.view.ContentNegotiatingViewResolver这个类来处理,由这个类来决定使用哪种view方式返回。

具体的转换方法如下:

再来看一下chrome请求头部和firefox请求头部的区别:

chrome的请求头中Accept的值为:*/*

对应上面的步骤:

1、获得请求头部中accept信息:*/*

2、获得转换器中支持Accept的media类型:*/*

3、转换器中支持的media类型是否兼容请求过来的Accept类型:*/*

4、根据请求等参数选择最佳的view

配置文件件配置了defaltView为MappingJackson2JsonView和MarshallingView,顺序匹配,为*时直接匹配上第一种,直播选择MappingJackson2JsonView解析。

firefox中请求头的Accept为text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

对应上面的步骤:

1、获得请求头部中accept信息:text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8

2、获得转换器中支持Accept的media类型:*/*

3、转换器中支持的media类型是否兼容请求过来的Accept类型:text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8

4、根据请求等参数选择最佳的view

配置文件件配置了defaltView为MappingJackson2JsonView和MarshallingView,顺序匹配,当匹配到application/xml时,直播返回使用MarshallingView解析。

以上步骤均是controller中没有加headers = { "Accept=application/json" }的情况,那为什么加了这段代码,firefox就可以运行了呢?

这时对应上面的步骤结果为:

1、获得请求头部中accept信息:text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8

2、获得转换器中支持Accept的media类型:application/json;q=0.8

3、转换器中支持的media类型是否兼容请求过来的Accept类型:application/json;q=0.8

4、根据请求等参数选择最佳的view:candidateViews类型为application/json,自然用MappingJackson2JsonView解析。

看上面的步骤大家已经明白了,加上Accept=application/json后获取的media类型就可以直接为application/json了,所以可以直接使用MappingJackson2JsonView解析,进而返回json数据格式。

再做了个实验,就是调换了一下defaultVeiws的配置顺序,把MarshallingView放在前面,在不加Accept=application/json,用chrome请求时,结果返回xml格式。

也就是说当accept是*/*时,他是顺序匹配的。

在spring mvc中,如果想返回的格式是指定的,也可以配置produces变量:

@RequestMapping(value = "/upload",produces="application/json;charset=UTF-8")

也可以达到同样的效果。

结论:

使用spring mvc时,如果返回的数据格式不正确,需要看一下请求头部的accept、controller层的header配置、以及配置文件中模板的渲染类型和配置顺序,通过这三个方式可以定位出原因。

时间: 2024-11-05 20:45:11

使用spring mvc返回JSON,chrome可以,firefox不行的问题定位的相关文章

spring mvc返回json字符串数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable

1.spring mvc返回json数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable 2. @RequestMapping(value = { "/actor_details" }, method = { RequestMethod.POST }) @ResponseBody public ResultObject actorDetails(@RequestBody ActorDetailsRequest req)

spring mvc返回json字符串的方式

spring mvc返回json字符串的方式 方案一:使用@ResponseBody 注解返回响应体 直接将返回值序列化json            优点:不需要自己再处理 步骤一:在spring-servlet.xml文件中配置如下代码 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans&quo

关于 Spring MVC 返回 json 字符串

Spring MVC 返回 json 字符串的几种方式: 1.通过 @ResponseBody 注解自动将返回对象转为 json,这种方法需要 jackson-core.jar 等相关 jar 包支持,项目如果通过 maven 管理,直接在 maven 中加入依赖: ,这样在 maven 依赖中会新增完整的三个 jar 包: 2.在 spring-MVC 配置文件中进行默认视图配置: 3.借助其他 json 工具进行转换:比如可以使用 gson 来完成转换,当然这种方式也得需要 gson 的相关

Spring MVC返回json视图时,如何将对象直接序列化成不带变量名做为根节点

Spring MVC返回json视图时,如何将对象直接序列化成不带变量名做为根节点的 json 报文 问题 问题描述起来比较拗口,其实就是用Spring MVC时,如何将对象映射成 json 报文时不把对象作为json的根节点.即使用@ResponseBody的效果. 比如,默认情况下,使用ModelAndView的addObject(key,object)或者ModelMap的addAttribute(key,object)保存完Java对象,然后交给Srping的视图解析器解析成json时,

Spring mvc 返回JSON 在IE 下提示下载 解决办法

http://www.blogjava.net/iamlibo/archive/2013/11/21/406646.html ———————————————————————————————————————————————————————————————————— 在IE低版本下接收Spring MVC @ResponseBody 返回的JSON 会提示下载保存.在chrome下没有问题.解决办法 是: <mvc:annotation-driven ignoreDefaultModelOnRedi

spring mvc 返回json的配置

转载自:http://my.oschina.net/haopeng/blog/324934 springMVC-servlet.xml 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

Spring MVC返回json格式

在使用SpringMVC框架直接返回json数据给客户端时,不同的版本有差异. 下面介绍两种类型的版本如何配置. 注意:这两种方法均已验证通过. 1.Spring3.1.x版本 1.1 dispatcher-servlet.xml配置文件如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans&q

Spring mvc 返回json格式 - 龙企阁 - 博客频道 - CSDN.NET

第一次使用spring mvc ,在此也算是记录一下以防忘记,希望有经验的朋友指出不足的地方 一.使用maven管理jar. [html] view plaincopyprint? <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-lgpl</artifactId> <version>1.9.6</version> &

Spring MVC返回json数据给Android端

原先做Android项目时,服务端接口一直是别人写的,自己拿来调用一下,但下个项目,接口也要自己搞定了,我想用Spring MVC框架来提供接口,这两天便抽空浅学了一下该框架以及该框架如何返回json数据.在这里边介绍两种个人觉得比较方便的两种方法(PS:其实是我现在只会这两种). 1.直接PrintWriter输出json数据 使用该方法时,可以自己拼凑json字符串,不过我并不赞同使用该方法,毕竟太容易出错了.所以这里我是先构建jsonobject对象,在将该对象打印出来.首先,我们要导入一