?
Ce document utilise Manuel du site Web PHP chinois Libérer
Portlet MVC里的控制器和Web MVC的很相似,在兩者之間移植代碼很簡(jiǎn)單。
Portlet MVC控制器構(gòu)架的基礎(chǔ)是
org.springframework.web.portlet.mvc.Controller
接口,如下所示。
public interface Controller { ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception; void handleActionRequest(ActionRequest request, ActionResponse response) throws Exception; }
如你所見,Portlet
Controller
接口需要兩個(gè)方法來處理Portlet
請(qǐng)求的兩個(gè)階段:動(dòng)作請(qǐng)求和顯示請(qǐng)求。動(dòng)作階段應(yīng)該能夠處理動(dòng)作請(qǐng)求,顯示階段應(yīng)該
能夠處理顯示請(qǐng)求,并返回合適的模型和視圖。
盡管Controller
接口是抽象的,但Spring Portlet MVC
提供了很多包含了各種各樣你需要的功能的控制器-它們中的大多數(shù)和Spring Web MVC里的控制器很類似。
Controller
接口只定義每個(gè)控制器需要的通用的功能
- 處理動(dòng)作請(qǐng)求,處理顯示請(qǐng)求,返回模型和視圖。
當(dāng)然,僅一個(gè)Controller
是不夠的。為了提供基本的功能,所有的Spring Portlet
Controller
從
AbstractController
繼承,后者可以訪問Spring
的ApplicationContext
和控制緩存。
表?16.3.?AbstractController
提供的功能
參數(shù) | 解釋 |
---|---|
requireSession |
表明當(dāng)前的
Controller 是否需要session。
所有的控制器都能使用這個(gè)功能。如果這樣的控制器收到請(qǐng)求時(shí),
session不存在,用戶會(huì)收到
SessionRequiredException 異常。 |
synchronizeSession |
如果需要控制器在處理用戶session時(shí)保持同步,使用
這個(gè)參數(shù)。更具體來說,擴(kuò)展的控制器會(huì)覆蓋handleRenderRequestInternal(..)
和handleActionRequestInternal(..) 方法,如果指定了這個(gè)參數(shù),
這兩個(gè)方法會(huì)在處理用戶session時(shí)保持同步。 |
renderWhenMinimized |
如果需要在portlet最小化狀態(tài)時(shí),控制器也顯示視圖, 把這個(gè)參數(shù)設(shè)為true。這個(gè)參數(shù)缺省是false,所以portlet在最小化狀態(tài) 時(shí),不顯示內(nèi)容。 |
cacheSeconds |
在需要控制器覆蓋當(dāng)前portlet定義的缺省緩存失效時(shí)間時(shí),
設(shè)置一個(gè)正的整數(shù)。這個(gè)參數(shù)缺省是-1 ,
表示不改變?nèi)笔〉木彺妫阉O(shè)為0 ,就是
確保不緩存結(jié)果。 |
requireSession
和
cacheSeconds
屬性是在
AbstractController
的父類
PortletContentGenerator
里聲明的。為了完整性,
把它們列在這里。
在你自己的控制器里繼承AbstractController
時(shí)
(不推薦這樣做,因?yàn)橐呀?jīng)有許多現(xiàn)成的控制器,它們可能有你需要的功能),僅需要覆蓋
handleActionRequestInternal(ActionRequest,
ActionResponse)
方法或
handleRenderRequestInternal(RenderRequest,
RenderResponse)
方法(或兩者都覆蓋),實(shí)現(xiàn)邏輯,
并返回 ModelAndView
對(duì)象(如果是
handleRenderRequestInternal
方法)。
handleActionRequestInternal(..)
和
handleRenderRequestInternal(..)
方法的缺省實(shí)現(xiàn)都會(huì)
拋出PortletException
,這和JSR-168規(guī)范API里的
GenericPortlet
的行為是一致的。所以只要覆蓋你的控制器
需要處理的方法。
下面簡(jiǎn)短的例子包含了一個(gè)類和一個(gè)在web應(yīng)用context里的聲明。
package samples; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import org.springframework.web.portlet.mvc.AbstractController; import org.springframework.web.portlet.ModelAndView; public class SampleController extends AbstractController { public ModelAndView handleRenderRequestInternal( RenderRequest request, RenderResponse response) throws Exception { ModelAndView mav = new ModelAndView("foo"); mav.addObject("message", "Hello World!"); return mav; } } <bean id="sampleController" class="samples.SampleController"> <property name="cacheSeconds" value="120"/> </bean>
為了使得一個(gè)簡(jiǎn)單的控制器工作,你只需要類似上面的類和在web應(yīng)用context里的聲明, 并且再設(shè)置一下處理器映射(見 第?16.5?節(jié) “處理器映射”)。
盡管你能夠繼承AbstractController
,
Spring Portlet MVC提供了不少具體的實(shí)現(xiàn),它們提供了許多在簡(jiǎn)單MVC應(yīng)用里常用的功能。
ParameterizableViewController
基本上
和上面的例子類似,除了你能指定web應(yīng)用context返回的視圖的名字。(不需要寫死視圖名稱)。
PortletModeNameViewController
把當(dāng)前的
Portlet的狀態(tài)作為視圖名,如果Portlet在View模式
(比如:PortletMode.VIEW
),這個(gè)“View”就是視圖名。
Spring Portlet MVC提供了和Spring Web MVC完全一致的
command controllers層次結(jié)構(gòu),提供方法來與數(shù)據(jù)對(duì)象交互
并且動(dòng)態(tài)地把參數(shù)從PortletRequest
綁定到數(shù)據(jù)對(duì)象上。數(shù)據(jù)對(duì)象不需要實(shí)現(xiàn)框架相關(guān)的接口,因而你可以
直接操作這些持久化對(duì)象。下面讓我們查看Command控制器提供的功能,來了解它們的使用:
AbstractCommandController
- Command控制器,可以用來創(chuàng)建自己的控制器,它能夠?qū)⒄?qǐng)求里的參數(shù)
綁定到指定的數(shù)據(jù)對(duì)象。這個(gè)類不提供表單功能,但它提供驗(yàn)證功能,并且
可以在控制器里指定如何處理帶有請(qǐng)求參數(shù)的Command對(duì)象。
AbstractFormController
-
提供表單提交支持的抽象控制器。你能夠?qū)Ρ韱芜M(jìn)行建模,通過從控制器
里得到的Command對(duì)象來填充表單。在用戶提交表單后,
AbstractFormController
會(huì)綁定字段、進(jìn)行驗(yàn)證,
然后把對(duì)象返回給控制器來做下一步的動(dòng)作。支持的功能有:無效表單提交(重新
提交)、驗(yàn)正和通常的表單流程。你需要實(shí)現(xiàn)方法來決定表單的顯示和成功時(shí)使用的
視圖。如果你需要表單,但不想在應(yīng)用context里指定用戶看到的視圖,使用這個(gè)
控制器。
SimpleFormController
-
一個(gè)具體的AbstractFormController
,
對(duì)使用對(duì)應(yīng)的command對(duì)象生成表單提供了更多的支持。
SimpleFormController
可以讓你在用戶成功地提交
表單或其它狀態(tài)時(shí),指定command對(duì)象,表單的視圖名以及頁(yè)面對(duì)應(yīng)的視圖名。
AbstractWizardFormController
–
具體的AbstractFormController
,它提交了向?qū)降慕涌? 來編輯跨多個(gè)頁(yè)面的command對(duì)象。支持多種用戶動(dòng)作:完成、取消或者頁(yè)面變化,所有這些
都可以簡(jiǎn)便地在視圖的請(qǐng)求參數(shù)里指定。
這些command控制器是非常強(qiáng)大的,為了有效地使用,需要對(duì)它們的原理有 細(xì)致的理解。在你開始使用它們前,務(wù)必仔細(xì)閱讀它們層次結(jié)構(gòu)的javadoc以及示例。
除了開發(fā)新的控制器,我們可以重用現(xiàn)有的portlet并且在
DispatcherPortlet
把請(qǐng)求映射指向它們。通過PortletWrappingController
,你能實(shí)例化一個(gè)
現(xiàn)有的Portlet
來作
Controller
,如下所示:
<bean id="wrappingController" class="org.springframework.web.portlet.mvc.PortletWrappingController"> <property name="portletClass" value="sample.MyPortlet"/> <property name="portletName" value="my-portlet"/> <property name="initParameters"> <value> config=/WEB-INF/my-portlet-config.xml </value> </property> </bean>
這會(huì)很有價(jià)值,因?yàn)榭梢允褂脭r截器來對(duì)送向這些portlet的請(qǐng)求進(jìn)行預(yù)處理和后處理。
而且也很方便,因?yàn)镴SR-168沒有提供對(duì)過濾機(jī)制的支持。比如,可以在一個(gè)MyFaces
JSR Portlet外面加上Hibernate的
OpenSessionInViewInterceptor
。