13.3.1.?AbstractController
和 WebContentGenerator
為了提供一套基礎設施,所有的Spring控制器都繼承了 AbstractController
,AbstractController
提供了諸如緩存支持和mimetype設置這樣的功能。
表?13.3.?AbstractController
提供的功能
功能 |
描述 |
supportedMethods
|
指定這個控制器應該接受什么樣的請求方法。通常它被設置成同時支持GET和POST,但是你可以選擇你想支持的方法。如果控制器不支持請求發送的方法,客戶端會得到通知(通常是拋出一個ServletException )。 |
requiresSession
|
指定這個控制器是否需要HTTP session才能正常工作。如果控制器在沒有session的情況下接收到請求,客戶端會因為拋出ServletException 而得到通知。 |
synchronizeSession
|
指定controller是否同步用戶的HTTP session。 |
cacheSeconds
|
指定controller通知客戶端對數據內容緩存的秒數,一般為大于零的整數。默認值為-1,即不緩存。 |
useExpiresHeader
|
指定Controller在響應請求時是否兼容HTTP 1.0 Expires header。缺省值為true 。 |
useCacheHeader
|
指定Controller在相應請求時是否兼容HTTP 1.1 Cache-Control header。默認值為true 。 |
當從AbstractController
繼承時,需要實現handleRequestInternal(HttpServletRequest, HttpServletResponse)
抽象方法,該方法將用來實現自己的邏輯,并返回一個ModelAndView
對象。下面這個簡單的例子演示了如何從AbstractController
繼承以及如何在applicationContext.xml中進行配置
package samples;
public class SampleController extends AbstractController {
public ModelAndView handleRequestInternal(
HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("hello");
mav.addObject("message", "Hello World!");
return mav;
}
}
<bean id="sampleController" class="samples.SampleController">
<property name="cacheSeconds" value="120"/>
</bean>
該controller返回的ModelAndView使用了硬編碼的視圖名(盡管這樣做不好),并通知客戶端將響應數據緩存2分鐘。除了通過以上方式創建和配置controller之外,還需要配置handler mapping(請參考第?13.4?節 “處理器映射(handler mapping)”),這樣該controller就可以工作了。
13.3.3.?MultiActionController
MultiActionController
將多個行為(action)合并在一個控制器里,這樣可以把相關功能組合在一起。MultiActionController
位于org.springframework.web.mvc.multiaction
包中,它通過將請求映射到正確的方法名來調用方法。當在一個控制器存在大量公共的行為,但是有多個調用入口時,使用MultiActionController
就特別方便。
表?13.4.?MultiActionController
提供的功能
功能 |
描述 |
delegate
|
MultiActionController 有兩種使用方式。第一種是你繼承MultiActionController ,并在子類中指定由MethodNameResolver 解析的方法(這種情況下不需要這個delegate參數)。第二種是你定義一個代理對象,由它提供MethodNameResolver 解析出來的方法(這種情況下,你必須使用這個配置參數定義代理對象)。 |
methodNameResolver
|
MultiActionController 需要一種策略,使其可以通過解析請求信息來獲得要調用的方法。這個解析策略由MethodNameResolver 這個接口定義的。這個參數允許你實現MethodNameResolver 接口,然后在控制器中使用你的策略。 |
MultiActionController
所支持的方法需要符合下列格式:
// anyMeaningfulName can be replaced by any methodname
public [ModelAndView | Map | void] anyMeaningfulName(HttpServletRequest, HttpServletResponse [, Exception | AnyObject]);
注意:在此不允許方法重載,因為MultiActionController
無法分辨出重載(overloading)了的方法。此外,你可以定義exception handler來處理方法中拋出的異常。
Exception
參數是可選的,它可以是任何異常,只要它是java.lang.Exception
或java.lang.RuntimeException
的子類。AnyObject
參數也是可選的,它可以是任何對象。HTTP Request中的參數會存在這個對象中,以便使用。
下面幾個例子示范了MultiActionController
正確的方法定義。
標準格式(跟Controller
接口定義的一樣)。
public ModelAndView doRequest(HttpServletRequest, HttpServletResponse)
下面這個方法支持Login
參數, 這個參數中包含從請求中抽取出來的信息。
public ModelAndView doLogin(HttpServletRequest, HttpServletResponse, Login)
下面這個方法可以處理Exception
。
public ModelAndView processException(HttpServletRequest, HttpServletResponse, IllegalArgumentException)
下面這個方法不返回任何數值。 (請參考后面的章節 第?13.11?節 “慣例優先原則(convention over configuration)”)
public void goHome(HttpServletRequest, HttpServletResponse)
This signature has a Map
return type (see the section entitled 第?13.11?節 “慣例優先原則(convention over configuration)” below).
下面這個方法返回一個Map
。 (請參考后面的章節第?13.11?節 “慣例優先原則(convention over configuration)”)
public Map doRequest(HttpServletRequest, HttpServletResponse)
MethodNameResolver
負責從請求中解析出需要調用的方法名稱。下面是Spring中內置的三個MethodNameResolver
實現。
-
ParameterMethodNameResolver
- 解析請求參數,并將它作為方法名。(對應http://www.sf.net/index.view?testParam=testIt
的請求,會調用 testIt(HttpServletRequest,HttpServletResponse)
方法)。使用paramName
配置參數,可以設定要檢查的參數。
-
InternalPathMethodNameResolver
-從路徑中獲取文件名作為方法名 (http://www.sf.net/testing.view
的請求會調用testing(HttpServletRequest,HttpServletResponse)
方法。
-
PropertiesMethodNameResolver
- 使用用戶自定義的屬性對象,將請求的URL映射到方法名。當屬性中包含/index/welcome.html=doIt
時,發到/index/welcome.html
的請求會調用doIt(HttpServletRequest, HttpServletResponse)
這個方法。 這個方法名解析器可以和PathMatcher
一起工作,比如上邊那個URL寫成/**/welcom?.html
也是可以的。
我們來看一組例子。首先是一個使用ParameterMethodNameResolver
和代理(delegate)屬性的例子,它接受包含參數名"method"的請求,調用方法retrieveIndex
:
<bean id="paramResolver" class="org....mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="method"/>
</bean>
<bean id="paramMultiController" class="org....mvc.multiaction.MultiActionController">
<property name="methodNameResolver" ref="paramResolver"/>
<property name="delegate" ref="sampleDelegate"/>
</bean>
<bean id="sampleDelegate" class="samples.SampleDelegate"/>
## together with
public class SampleDelegate {
public ModelAndView retrieveIndex(HttpServletRequest req, HttpServletResponse resp) {
return new ModelAndView("index", "date", new Long(System.currentTimeMillis()));
}
}
當使用上面的代理對象時,我們也可以使用PropertiesMethodNameRseolver
來匹配一組URL,將它們映射到我們定義的方法上:
<bean id="propsResolver" class="org....mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<value>
/index/welcome.html=retrieveIndex
/**/notwelcome.html=retrieveIndex
/*/user?.html=retrieveIndex
</value>
</property>
</bean>
<bean id="paramMultiController" class="org....mvc.multiaction.MultiActionController">
<property name="methodNameResolver" ref="propsResolver"/>
<property name="delegate" ref="sampleDelegate"/>
</bean>