1. 程式人生 > >Spring MVC(3)Spring MVC 高級應用

Spring MVC(3)Spring MVC 高級應用

ann 默認 chap coo cto 合作 視圖解析器 eric 不同

  一、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 高級應用