Spring 學(xué)習筆記(二)-- AbstactController
控制器是 MVC 設計模式的一部分,通過(guò)定義服務(wù)接口提供對應用行為的訪(fǎng)問(wèn)??刂破鳙@取用戶(hù)輸入的數據并作簡(jiǎn)單的轉換處理成符合服務(wù)模塊的規則并傳入服務(wù)模塊,經(jīng)過(guò)服務(wù)模塊的處理給用戶(hù)返回視圖。 Spring 的控制器以抽象的方式實(shí)現了這種概念,并且有很多樣的控制器在不同情況下可供使用,包括了確定視圖的控制器,基于命令的控制器,還有執行向導式邏輯的控制器,在這里僅舉幾個(gè)例子。
Spring 的控制器結構的基礎是 org.springframework.web.servlet.mvc.Controller 接口。
可以看到, Controller 接口定義了一個(gè)方法,負責處理一個(gè)請求并通過(guò)合適的模塊返回視圖。在 Spring 通過(guò) ModelAndView 和 Controller 實(shí)現。 Controller 接口是非常抽象的, Spring 提供許多實(shí)現了這個(gè)接口的控制器,這些控制器包含了許多功能,在你需要的時(shí)候可以使用。而 Controller 接口只是定義了一個(gè)方法負責最基本的職責。
Spring 定義的控制器并不是直接實(shí)現 Controller 接口,而是實(shí)現了 AbstractController,AbstractorController 實(shí)現了 Controller 接口。
下面表格是 AbstractController 提供的功能點(diǎn)。
Feature | 說(shuō)明 |
supportMethods | 表明控制器會(huì )接收哪些方法。一般會(huì )默認設置GET 和POST ,你也可以修改這些方法。如果一個(gè)請求攜帶的方法是這個(gè)控制器不支持的,客戶(hù)端會(huì )被告知,拋出ServletException 。 |
requireSession | 表明控制器是否需要HTTP session 。 |
synchronizeOnSession | 確定是否對HTTP session 實(shí)行同步。 |
cacheSeconds | 設置cache 時(shí)間。默認是-1 ,則不設置。 |
useExpiresHeader | 為了與HTTP1.0 的‘Expires’ 兼容. 默認true |
useCacheHeader | 為了與HTTP1.0 的‘Cache-Control’ 兼容,默認true |
當你用 AbstractController 作為你控制器的父類(lèi)的時(shí)候,你只需要改寫(xiě) handleRequestInternal(HttpServletRequest, HttpServletResponse) 方法,實(shí)現業(yè)務(wù)邏輯,并返回 ModelAndView 對象。下面是一個(gè)下面是一個(gè)例子。
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
上面這個(gè)控制器產(chǎn)生了 cache 指令告訴客戶(hù)端 cache 保持 2 分鐘。我們看到一個(gè)編碼的壞習慣,就是返回視圖的時(shí)候用了硬編碼。
上面講到的是從 spring-reference.pdf 翻譯過(guò)來(lái)的,部分加上自己的理解?,F在再結合源碼可以更深入的了解到上面的機制是怎么運行的。
首先我們現看一下 AbstractController 的類(lèi)層次圖。
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
似比較復雜。一步一步來(lái)看。
現看 AbstractController 類(lèi)。 Spring 定義的所有控制器都繼承于它。它有一個(gè)屬性
private boolean synchronizeOnSession = false ;
這個(gè)屬性的作用在上面有提到過(guò)。上面提到的其他屬性在 AbstractController 的父類(lèi)定義。
另外就是實(shí)現了 Controller 接口的方法:
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
首先是委托 WebContentGenerator 作一些準備的工作。作一些什么樣的工作呢?我們再看 WebContentGenerator 的 checkAndPrepare () 方法。注意一下, WebContentGenerator 初始化時(shí)將默認的處理方法為 get,post,head 。代碼如下:
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
restrictDefaultSupportedMethods 默認為 true 。
this . useExpiresHeader 處理根據上文知道是為了兼容 HTTP1.0.
this . useCacheControlHeader 如果用戶(hù)有使用 cache 指令,則進(jìn)行處理,用 Servlet 最基本的 response 設置。
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
這段代碼結合上文就可以很好的理解 supportMethods 拋出異常的相關(guān)情況。
applyCacheSeconds(response,cacheSeconds,lastModified) 方法中,參數 lastModified 是在 ApplicationController 的 handleRequest() ,有這樣傳入 this instanceof LastModified ,判斷這個(gè)控制類(lèi)是否實(shí)現了 LastModified 接口 , 在這個(gè)方法實(shí)際上作了 cacheSeconds 屬性的工作。
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
常量 HEADER_CACHE_CONTROL =“ Cache-Control” ,這是對 cache 的處理。
現在回到 AbstractController 的 handleRequests() 方法, checkAndPrepare ()處理完之后,再根據 synchronizeOnSession 判斷是否需要同步。 handleRequestInternal(request, response) 方法是真正處理邏輯的地方,這也是前面一個(gè)例子為什么要重寫(xiě)這個(gè)方法的原因。
聯(lián)系客服