Xml代码 
<bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >  
    <property name="messageConverters">  
  <list>  
   <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 -->  
  </list>  
</property>  
</bean>      
<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />

<bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" > 
    <property name="messageConverters"> 
  <list> 
   <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 --> 
  </list> 
</property> 
</bean>   
<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />

需要以下两个jar包:

Xml代码 
<dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.5.5" conf="runtime->default" />  
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.5.5" conf="runtime->default" />

<dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.5.5" conf="runtime->default" /> 
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.5.5" conf="runtime->default" />

Java代码 
@RequestMapping(value="/nogood", method=RequestMethod.GET)   
public @ResponseBody CmUser execute(String userid) {   
  CmUser u = new CmUser();   
  u.setAge(16);   
  u.setName("测试用户");   
  return u;   
}

通过上面的代码可以实现java对象直接可以转json对象,下面是项目中的配置

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="webBindingInitializer">
            <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
                <property name="conversionService" ref="conversionService"/>
            </bean>
        </property>
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
                <bean class="org.springframework.http.converter.StringHttpMessageConverter" >
                    <property name = "supportedMediaTypes">
                           <list>
                                   <value>text/plain;charset=UTF-8</value>
                          </list>
                     </property> 
                </bean>
                <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
                <!-- 注:开启此类需相关jar包持:javax.xml.bind.JAXBException
                <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
                <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
                <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
                 -->
                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
            </list>
        </property>
    </bean>

下面分析@ResponseBody 注解

在SpringMVC中可以在Controller的某个方法上加@ResponseBody注解,表示该方法的返回结果直接写入HTTP response body中。

但是实际使用中发现最后生成的response中"Content-Type"的值不正确。

Spring使用AnnotationMethodHandlerAdapter来处理@ResponseBody,该类再使用一些HttpMessageConverter来具体处理信息。

AnnotationMethodHandlerAdapter使用request header中"Accept"的值和messageConverter支持的MediaType进行匹配,然后会用"Accept"的第一个值写入 response的"Content-Type"。

一般的请求都是通过浏览器进行的,request header中"Accept"的值由浏览器生成。

Chrome生成的值为application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

IE8生成的值为application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*

所以最后写入response中"Content-Type"的值为"application/xml"或"application/x-ms-application"。

但我们一般会在标注@ResponseBody的方法上返回String或byte[]类型的结果,期望的"Content-Type"的值应为"text/plain"或"application/octet-stream"。

这样导致了浏览器不能正确处理返回的内容。

实际上Spring在用HttpMessageConverter处理的过程中首先会判断response header中有没有写入"Content-Type",如果没有写入的话才会使用request header中"Accept"的第一个值。

但是由于Spring对HttpServletResponse进行了封装,实际上使用的是ServletServerHttpResponse,这个类有一个对真正的HttpServletResponse的引用。

判断response header的过程中使用的是ServletServerHttpResponse的getHeaders()方法,但该方法并没有返回真正的HttpServletResponse中的header。(这应该有问题吧?)

所以我们虽然可以在Controller的方法中加入对HttpServletResponse的引用,然后设置"Content-Type"的值,但是并不会起作用。

通过上面的分析,@ResponseBody看来是无法使用了。

还可以参考下面文章:http://www.iteye.com/topic/1124054
http://www.360doc.com/content/12/0809/11/9600761_229177035.shtml

 
0

spring mvc Response header content type的更多相关文章

  1. ASP.NET MVCでResponse Headerのサーバーバージョンをどうやって隠しますか?

    本来是发布在客户的Wiki上的,所以用日语写. ---------------------------------------------------------------------------- ...

  2. 从content-type设置看Spring MVC处理header的一个坑

    我们经常需要在HttpResponse中设置一些headers,我们使用Spring MVC框架的时候我们如何给Response设置Header呢? Sooooooooooooo easy, 看下面的 ...

  3. spring mvc获取header

    两种方法: 1.在方法参数中加入@RequestHeader 2.在类级别注入HttpServletRequest 建议使用第二种方法,这样可避免每个方法都加入HttpHeaders参数 @Contr ...

  4. spring MVC之返回JSON数据(Spring3.0 MVC)

    方式一:使用ModelAndView的contentType是"application/json" 方式二:返回String的            contentType是&qu ...

  5. 零基础搭建 spring mvc 4 项目(本文基于 Servlet 3.0)

    作者各必备工具的版本如下: Tomcat:apache-tomcat-7.0.63 (下载链接) Java EE - Eclipse:Luna Service Release 1 v4.4.1 (下载 ...

  6. ajax使用向Spring MVC发送JSON数据出现 org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported错误

    ajax使用向Spring MVC发送JSON数据时,后端Controller在接受JSON数据时报org.springframework.web.HttpMediaTypeNotSupportedE ...

  7. Spring MVC Content Negotiation 转载

    Spring MVC Content Negotiation 2017年11月15日 00:21:21 carl-zhao 阅读数:2983   Spring MVC有两种方式生成output的方法: ...

  8. Content Negotiation using Spring MVC

    There are two ways to generate output using Spring MVC: You can use the RESTful @ResponseBody approa ...

  9. springboot Serving Web Content with Spring MVC

    Serving Web Content with Spring MVC This guide walks you through the process of creating a "hel ...

随机推荐

  1. windows server2012 nVME和网卡等驱动和不识别RAID10问题

    安装2012---不识别M.2 nVME,下官方驱动,注入到系统里 缺多驱动---用ITSK万能驱动添加:|Win8012R2.x64(可解决不支持操作系统,win10与server2012R2通用) ...

  2. 【C语言基础】unsigned short类型用于循环的一个难点

    我在我的知识星球:“C语言解惑课堂”里的第一篇提出一个问题:[第1篇][C语言基础][unsigned short类型用于循环的一个难点]要查看更多的C语言难点解析或者需要提问的同学,微信扫扫文末我的 ...

  3. 网络安全攻击与防护--HTML学习

    第一节. HTML基本语法(文末有对该文视频讲解) HTML的官方介绍什么的我就不说了,打字也挺累的,只简单介绍一下吧,其他的懂不懂都没关系. HTML全称为Hypertext Markup Lang ...

  4. csdn论坛页抓取

    抓取csdn论坛 实现功能 获取论坛分类所有链接,并拼接成推荐精华页的完成的链接 获取推荐精华页的帖子状态,赏分,帖子标题,作者,发布时间,回复量,查看量,最后发表时间 置顶内容不爬取,只打印置顶内容 ...

  5. Spring源码剖析7:AOP实现原理详解

    前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...

  6. C#_细说Cookie_Json Helper_Cookies封装

    阅读目录 开始 Cookie 概述 Cookie的写.读过程 使用Cookie保存复杂对象 Js中读写Cookie Cookie在Session中的应用 Cookie在身份验证中的应用 Cookie的 ...

  7. HDFS介绍~超详细

    HDFS(Hadoop Distributed File System)   (1) HDFS--Hadoop分布式文件存储系统   源自于Google的GFS论文,HDFS是GFS的克隆版 HDFS ...

  8. CodeForces 909D

    题意略. 思路: 将字符分桶,然后暴力去扫,扫完合并.假设有k个桶,每个桶里有n / k个数,那么我们应该要扫 n / (2 * k)次,每次的复杂度是k,最后算得复杂度是O(n). 详见代码: #i ...

  9. 浅谈jQuery中的Ajax

    浅谈jQuery中的Ajax 一.前言 jQuery 对 Ajax 操作进行了封装, 在 jQuery 中最底层的方法时 $.ajax(), 第二层是 load(), $.get() 和 $.post ...

  10. 用故事解析setTimeout和setInterval(内含js单线程和任务队列)

    区别: setTimeout(fn,t): 延迟调用,超过了时间就调用回调函数,返回一个id,使用clearTimeout(id)取消执行. 注意:取消了里面的回调函数就不执行了哦,而不是取消的时候就 ...