Spring MVC(3)Spring MVC 高級應用
一、Spring MVC 的數據轉換和格式化
前面的應用,都只是用HandlerAdapter去執行處理器。
處理器和控制器不是一個概念,處理器是在控制器功能的基礎上加上了一層包裝,有了這層包裝,在HTTP請求達到控制器之前它就能夠對HTTP的各類消息進行處理。
首先當一個請求到達 DispatcherServlet 的時候,需要找到對應的HandlerMapping,然後根據 HandlerMapping 去找到對應的 HandlerAdapter 執行處理器。處理器在要調用的控制器之前,需要先獲取 HTTP (即jsp文件對應的網頁)發送過來的信息,然後將其轉變為控制器的各種不同類型的參數,這就是各類註解能夠得到豐富類型參數的原因。
它首先用 HTTP 的消息轉換器(HttpMessageConverter)對消息轉換,但是這是一個比較原始的過程,它是String 類型和文件類型比較簡易的轉換,還需要進一步轉換為 POJO 或者其他豐富的參數類型。為了擁有這樣的能力,Spring 4 提供了轉換器和格式化器,這樣通過註解的信息和參數的類型,它就能把 HTTP 發送過來的各種消息轉換為控制器所需要的各類參數了。
當處理器處理完了這些參數的轉換,它就會進行驗證,驗證表單的方法已經提過。完成了這些內容,下一步就是調用開發者所提供的控制器了,將之前轉換成功的參數傳遞進去,這樣我們開發的控制器就能夠得到豐富的 Java 類型的支持了,進而完成控制器的邏輯,控制器完成了對應的邏輯,返回結果後,處理器如果可以找到對應處理結果類型的 HttpMessageConverter 的實現類,它就會調用對應的 HttpMessageConverter 的實現類方法對控制器返回的結果進行 HTTP 轉換,這一步不是必須的,可以轉換的前提是能夠找到對應的轉換器,做完這些處理器的功能就完成了。
接下來就是關於視圖解析和視圖解析器的流程了,整個過程是比較復雜的,有時候要自定義一些特殊的轉換規則,比如如果需要和第三方合作,合作方可能提供的不是一個良好的JSON 格式,而是一些特殊的規則,這個時候就可能需要使用自定義的消息轉換規則,把消息類型轉換為對應的 Java 類型,從而簡化開發。
對於 Spirng MVC ,在XML上配置了<mvc:annotation-driven>,或者 Java 配置的註解上加入@EnableWebMvc 的時候,Spring IoC 容器會自定義生成一個關於轉換器和格式化器的類實例----------FormattingConversionServiceFactoryBean,這樣就可以從 Spring IoC容器中獲取這個對象了。FormattingConversionServiceFactoryBean可以生成DefaultFormattingConversionService類對象,類對象繼承了一些類,並實現了許多接口。
其中,頂層接口是ConversionService接口,它還實現了轉換器的註冊機(ConverterRegistry)和格式化器註冊機(FormatterRegistry)兩個接口。
而事實上 Spring MVC 已經註冊了一些常用的轉換器和格式化器。
在運行控制器之前,處理器就會使用這些轉換器把 HTTP 的數據轉換為對應的類型,用以填充控制器的參數,這就是為什麽可以在控制器保持一定的規則下就能得到參數的原因。
當控制器返回數據模型後,再通過 Spirng MVC 後面對應的流程渲染數據,然後顯示給客戶端。
在Java類型轉換之前,在 Spring MVC 中,為了應對 HTTP 請求,它還定義了HttpMessageConverter,它是一個總體的接口,通過它可以讀入HTTP的請求內容,即在讀取 HTTP 請求的參數和內容的時候會先用 HttpMessageConverter 讀出,做一次簡單轉換為 Java 類型,主要是字符串,然後就可以使用各類轉換器進行轉換了,在邏輯業務處理完成後,還可以通過它把數據轉換為相應給用戶的內容。
對於轉換器而言,在 Spring 中有兩大類,一種是由 Converter 接口所定義的,另外一種是 GenericConverter,它們都可以使用註冊機註冊。但是,它們都是來自於 Spring Core 項目,它的作用範圍是 Java 內部各種類型之間的轉換。
1.HttpMessageConverter 和 JSON 消息轉換器
HttpMessageConverter 是定義從 HTTP 接收請求信息和應答給用戶的,用的比較多的實現類是 MappingJackson2HttpMessageConverter,這是一個關於 JSON 消息的轉換類,通過它能夠把控制器返回的結果在處理器內轉換為 JSON 數據。
(1)註冊MappingJackson2HttpMessageConverter
jsonConverter中的application/json;charset=UTF-8表示 HTTP 相應請求的類型是一個 JSON 類型,當在控制器中使用 @ResponseBody 的時候,Spring MVC 便會將應答請求轉變為關於 JSON 的類型。這樣的一次轉換,就意味著處理器會在控制器返回結果後,遍歷其項目中定義的各類HttpMessageConverter 實現類,由於 MappingJackson2HttpMessageConverter 定義為支持 JSON 數據的轉換,它和@ResponseBody 所定義的相應類型一樣,因此 Spirng MVC 就知道采用 MappingJackson2HttpMessageConverter 將控制器返回的結果進行處理,這樣就轉換為了 JSON 數據集了。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jsonConverter" /> </list> </property> </bean> <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean>
(2)通過 @ResponseBody 註解可以使用上面配置的消息轉換器
當通過@ResponseBody註解後,Spring MVC 就會將控制器返回的結果通過類型判斷找到 MappingJackson2HttpMessageConverter 實例,進而在處理器內部轉變成 JSON 類型。
@RequestMapping(value = "/getRole") // 註解,使得Spring MVC把結果轉化為JSON類型響應,進而找到轉換器 @ResponseBody public Role getRole(Long id) { Role role = roleService.getRole(id); return role; }
(3)測試(復習:這裏getRole(Long id)是通過默認的參數一致性進行參數傳遞的,不需要加註解)
日誌:
第一行,返回 JDBC 連接後,然後,第二行是關鍵:
通過之前定義過的處理器規則:將[com.ssm.chapter16.pojo.Role@39c434fa]轉換成"application/json"形式,通過[MappingJackson2HttpMessageConverter@1ec15d1b] 實例
org.springframework.jdbc.datasource.DataSourceUtils: Returning JDBC Connection to DataSource org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor:
Written [com.ssm.chapter16.pojo.Role@39c434fa] as "application/json" using
[org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@1ec15d1b] org.springframework.web.servlet.DispatcherServlet: Null ModelAndView returned to DispatcherServlet with name ‘dispatcher‘: assuming HandlerAdapter completed request handling org.springframework.web.servlet.FrameworkServlet: Successfully completed request org.springframework.beans.factory.support.AbstractBeanFactory: Returning cached instance of singleton bean ‘SqlSessionFactory‘
HttpMessageConverter 的主要作用在於 Java 和 HTTP 之間的消息轉換。
2.一對一轉換器(Converter)
3.數組和集合轉換器 GenericConverter
4.格式化器(Formmater)
二、為控制器添加通知
三、處理異常
四、國際化
1.概述
2.MessageSource接口
3.CookieLocaleResolver 和 SessionLocalerResolver
4.國際化攔截器(LocaleChangeInterceptor)
5.開發國際化
Spring MVC(3)Spring MVC 高級應用