1. 程式人生 > >SpringMVC中@ResponseBody的問題

SpringMVC中@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看來是無法使用了。