Spring3引入了較Spring2的PropertyEditor
更增強大、通用的Convert/Format SPI
,Convert SPI
能夠實現任意類型的轉換;Format SPI
支持國際化,並在前者的基礎上實現了String與任意類型的轉換。這兩類SPI屬於spring-core
,被整個spring-framework
共享,是一種通用的類型轉換器。java
HttpMessageConverter
雖然功能上也表現爲HttpMessage
與任意類型的轉換,但其接口和Convert SPI
並無繼承關係。HttpMessageConverter
屬於spring-web
。HttpMessage
是SpringMVC對Servlet
規範中HttpServletRequest
和HttpServletResponse
的包裝,所以接受請求時須要把HttpMessage
轉換成用戶須要的數據,在生成響應時須要把用戶生成的數據轉換成HttpMessage
。若是用戶在XML的<mvc:message-converters>
中沒有指定register-defaults=false
,SpringMVC默認至少會註冊一些自帶的HttpMessageConvertor
(從前後順序排列分別爲ByteArrayHttpMessageConverter
、StringHttpMessageConverter
、ResourceHttpMessageConverter
、SourceHttpMessageConverter
、AllEncompassingFormHttpMessageConverter
)。web
若是後端服務使用Restful API
的形式,通常使用JSON做爲先後端通訊的格式規範,因爲SpringMVC自帶MappingJackson2HttpMessageConverter
,在依賴中引入jackson後,容器會把該轉換器自動註冊到converter鏈的末尾。ajax
Http請求中有幾個經常使用的部分能夠用來傳遞業務信息,以常見的Get
和Post
方法爲例。spring
是否可用 | URL | Parameter | Header | Body |
---|---|---|---|---|
Get | 是 | 是 | 是 | 否 |
Post | 是 | 否 | 是 | 是 |
那麼上述的4個部分都是用HttpMessageConverter
來進行類型轉換的嗎?顯然不是,HttpMessageConverter
和Convert SPI
各有分工, HttpMessageConverte
只負責解析Http包的Body體部分1,其他部分都交由相關的Convert SPI
處理2。後端
是否支持 | URL | Parameter | Header | Body |
---|---|---|---|---|
HttpMessageConverter | 否 | 否 | 否 | 是 |
Convert SPI | 是 | 是 | 是 | 否 |
除上表所示以外,SpringMVC還有一些須要Convert SPI
的場景,如讀取Cookie值的@CookieValue
(本質是Header),解析矩陣URL的@MatrixVariable
(本質是URL),讀取本地會話的@SessionAttribute
,解析SpEL的@Value
。mvc
在SpringMVC中,單次請求的整個處理流程中有哪些地方須要類型轉換?以Delete /ajax/shop/12345/blacklist?id=1
請求爲例,後端對應的處理方法以下。app
@DeleteMapping("/ajax/{shopId}/blacklist") @ResponseBody public boolean deleteBlackItem(@RequestParam Integer id, @PathVariable Integer shopId) { //省略 return true; }
因爲請求的URL爲String類型,而接受的參數id
和shopId
都是Integer類型,所以Spring會自動查找合適的Converter
(具體實現爲StringToNumberConverterFactory
的工廠產品)把字符串「12345」
和「1」
轉化爲數字12345
和1
,分別賦值給shopId
和id
。處理完業務邏輯後,方法返回true
,但須要將其格式化成String類型的「true」
才能輸出到響應的Body中,這時Spring就會使用StringToBooleanConverter
來完成轉換。以下圖所示,除了上述常見的數據綁定和格式化顯示功能,數據驗證功能(JSR-303
)基於數據綁定也間接利用了這兩套SPI。spa
在SpringMVC處理請求時,HttpMessageConverter
和Convert SPI
分別用來反序列化請求的Body和非Body部分,即HttpMessageConverter
是一套小型、獨立、額外爲用戶提供的專門的Body體的類型轉換器;而Convert SPI
則與PropertyEditor
相似,能夠處理更爲通用的類型轉換。3d