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
相關文章
相關標籤/搜索