• spring mvc Response header content type


    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 AOP实现业务依赖解耦
    对Java提供的锁机制的一些思考
    关于数据库优化的一些想法
    漫谈使用Kafka作为MQ中间件
    数据库事务隔离引发的关于锁机制的思考
    使用Redis作为高速缓存
    Docker 构建映像
    Centos7 Nginx开机启动
    Docker 设置固定网络IP
    CentOS docker 常用命令
  • 原文地址:https://www.cnblogs.com/lizhonghua34/p/6062060.html
Copyright © 2020-2023  润新知