1. 程式人生 > >Spring MVC使用篇(三)—— 處理器對映器和介面卡

Spring MVC使用篇(三)—— 處理器對映器和介面卡

文章目錄

1、重溫請求流程

  在Spring MVC的架構環境下,使用者在Web端觸發了請求,請求會先通過前端控制器(DispatcherServlet),然後前端控制器(DispatcherServlet)會請求處理器對映器(HandlerMapping)尋找處理該請求的Handler(或帶攔截器的Handler鏈),接著前端控制器(DispatcherServlet)會根據處理器對映器(HandlerMapping)傳來的Handler(或帶攔截器的Handler鏈)與配置的處理器介面卡(HandlerAdapter)進行匹配,找到可以處理此Handler(或帶攔截器的Handler鏈)型別的處理器介面卡(HandlerAdapter),進而該處理器介面卡(HandlerAdapter)呼叫自己的handler方法,利用Java的反射機制去執行具體的Controller方法並獲得ModelAndView檢視物件。

2、Spring MVC預設的註解配置

2.1 在Spring 3.1之前

  Spring MVC預設載入的註解的處理器對映器和處理器介面卡分別為DefaultAnnotationHandlerMapping、AnnotationMethodHandlerAdapter。它們位於Spring MVC的核心jar包的org.springframework.web.servlet.mvc.annotation包下。

2.2 在Spring 3.1之後

  DefaultAnnotationHandlerMapping、AnnotationMethodHandlerAdapter已經被列為國企的對映器和介面卡,Spring MVC增加了新的基於註解的處理器對映器和介面卡,分別為RequestMappingHandlerMapping和RequestMappingHandlerAdapter,它們同樣位於Spring MVC的核心jar包的org.springframework.web.servlet.mvc.method.annotation包下。

3、配置註解的處理器對映器和介面卡方式

3.1 第一種配置方式

  第一種配置方式和費註解的處理器介面卡和對映器的配置一樣,宣告相關的bean即實現即可,配置如下:

<!--註解對映器-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
    <!--註解介面卡-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"
/>

3.2 第二種配置方式

  第二種配置方式,使用“<mvc:annotation-driven />”標籤來配置。annotation-driven標籤是一種簡寫模式,使用預設配置代替了一般的手動配置。annotation-driven標籤會自動註冊處理器對映器和處理器介面卡(Spring 3.1 至 Spring 4 皆使用RequestMappingHandlerMapping和RequestMappingHandlerAdapter)。並且除此之外還提供了資料繫結支援,例如@NumberFormatannotation支援、@DateTimeFormat支援、@Valid支援、讀寫XML的支援(JAXB)和讀寫JSON的支援(Jackson)。在實際開發中,為了提高開發效率,使用最多的就是基於annotation-driven標籤的配置。annotation-driven標籤的配置十分簡單,如下所示。

<!--配置基於註解的處理器介面卡與處理器對映器-->
    <mvc:annotation-driven/>

4、讓註解的處理器對映器和介面卡找到註解的Handler

  為了讓註解的處理器對映器和介面卡找到註解的Handler,有兩種配置方式。

  • 在springmvc.xml中宣告相關的bean資訊即可;
    <bean class="com.ccff.controller.FruitsController" />
  • 使用掃描配置,對某一個包下的所有類進行掃描,找出所有使用@Controller註解的Handler控制類;
    <!--使用掃描配置,對某一個包下面的所有類進行掃描,
    找出所有使用@Controller註解的Handler控制器類-->
    <context:component-scan base-package="com.ccff.controller"/>

注意:如果不使用annotation-driven標籤配置註解的處理器對映器和介面卡,而採用手動配置,那麼必須保證基於註解的處理器對映器和介面卡要成對配置,不然會沒有效果。還有一點需要注意,如果在測試過程中出現“java.lang.IllegalArgumentException”,則說明使用了JDK 8.0的環境,由於Spring 3.x版本不支援JDK 8.0,因此需要更換編譯環境。

5、非註解的處理器對映器

  • BeanNameUrlHandlerMapping類
    • 對映規則:將bean的name作為url進行查詢,需要在配置Handler時指定beanname(就是url)。
    • 先在springmvc.xml配置檔案中新增處理器對映器;
    • 在配置Handler時需要指定beanname(就是url);
<!-- 先在springmvc.xml配置檔案中新增處理器對映器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!--  在配置Handler時需要指定beanname(就是url) -->
<bean name="/query/queryAllFruits.action" class="com.ccff.controller.FruitsController" />
  • SimpleUrlHandlerMapping類
      SimpleUrlHandlerMapping可以通過內部引數配置請求的url和handler的對映關係。樣例配置如下:
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="someCheckInterceptors1"/>
                <ref bean="someCheckInterceptors2"/>
            </list>
        </property>
        <property name="mappings">
            <props>
                <prop key="user.action">userController</prop>
                <prop key="product.action">productController</prop>
                <prop key="other.action">otherController</prop>
            </props>
        </property>
    </bean>

  在SimpleUrlHandlerMapping的bean標籤對中,可以通過property屬性配置攔截器和相關的Handler處理器的URL的對映關係。在上面的樣例中添加了兩個攔截器配置,和三個Handler處理器的URL對映。
  以水果商城案例為例,使用SimpleUrlHandlerMapping處理器對映器配置如下:

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/queryFruits_test1.action">fruitsController</prop>
                <prop key="/queryFruits_test2.action">fruitsController</prop>
            </props>
        </property>
    </bean>
    <bean id="fruitsController" class="com.ccff.controller.FruitsController" />

  這裡配置了兩個不同的URL,但是對應的都是同一個Controller配置。也就是說,在瀏覽器上發出兩個不同的URL請求,會得到相同的處理結果。

  • ControllerClassNameHandlerMapping類
      ControllerClassNameHandlerMapping可以使用CoC管理有限原則(conventionover configuration)的方式來處理請求,對於普通的Controller,會把其類名“xxxController”對映到“/xxx*”的請求URL。對於MultiActionController型別的Controller,ControllerClassNameHandlerMapping會把其類名“xxxController”以及其中的方法“yyy”對映到“/xxx/yyy.action”(.action對應設定的dispatcher-servlet的url-pattern)的請求URL。樣例配置如下:
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />

6、非註解的處理器介面卡

  • SimpleControllerHandlerAdapter
      SimpleControllerHandlerAdapter介面卡支援所有實現了Controller介面的Handler控制器,開發者如果編寫了實現Controller介面的控制器,那麼SimpleControllerHandlerAdapter介面卡會執行Controller的具體方法。
      以水果商城案例為例,配置處理器介面卡SimpleControllerHandlerAdapter如下:
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
  • HttpRequestHandlerAdapter
      HttpRequestHandlerAdapter要求編寫的Handler實現HttpRequestHandler介面。因此在非註解的Handler編寫中,Controller需要實現HttpRequestHandler介面,重寫handleRequest方法。配置如下:
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
  • AnnotationMethodHandlerAdapter

小貼士
  通過上面的整理,我們可以知道,處理器對映器就是根據URL來查詢Handler,處理器介面卡就是按照它要求的規則(handler instanceof XXX介面)去執行Handler。但是這種開發模式有一個缺點,一個Handler類中只能編寫一個方法,這對於大量請求處理邏輯真是勉為其難了,這種問題就可以通過註解的處理器對映器和介面卡就可以很好的解決了。