如上所示,这是Spring Portlet MVC的整个工作流程:
DispatcherPortlet 作为前端控制器,负责接收所有到Portlet的请求
(1) 当Portlet请求发送到DispatcherPortlet时,它利用PortletMVC的HandlerMapping来找到一个合适的Handler(也就是controller)来处理当前请求
- <portlet>
- <portlet-name>helloWorld</portlet-name>
- <portlet-class>
- org.springframework.web.portlet.DispatcherPortlet
- </portlet-class>
- <supports>
- <mime-type>text/html</mime-type>
- <portlet-mode>view</portlet-mode>
- </supports>
- <resource-bundle>content.Language-ext</resource-bundle>
- <portlet-info>
- <title>HelloWorld</title>
- </portlet-info>
- </portlet>
(2) PortletMVC 提供了一个PortletModeHandlerMapping,它实现了HandlerMapping接口,并且它基于当前Portlet的模式(view/edit/help....)来选择恰当的Handler.这个模式->Handler的映射规则配置在 <portlet-name>-portlet.xml ,它是该portlet的Spring配置文件
比如:
- <beans ... >
- <bean id="helloWorldController"
- class="chapter07.code.listing.HelloWorldController"/>
- <bean id="portletModeHandlerMapping"
- class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
- <property name="portletModeMap">
- <map>
- <entry key="view">
- <ref bean="helloWorldController" />
- </entry>
- </map>
- </property>
- </bean>
- </beans>
在这个例子中,我们可以看到PortletModeHandlerMapping将view模式匹配到了HelloWorldController 作为Handler,所以这个HellowWorldController有能力处理render类型的请求(对应view模式)
(3) 于是,这个DispatcherPortlet会指派HelloWorldController,而HelloWorldController处理了render类型的请求,然后返回一个ModelAndView对象给DispatcherPortlet.
- public class HelloWorldController implements Controller{
- public void handleActionRequest(ActionRequest request,
- ActionResponse response)throws Exception {
- }
- //这个是render类型请求的处理函数,请求结果被封装在ModelAndView对象中返回给调用者,也就是返回给DispatcherPortlet
- public ModelAndView handleRenderRequest
- (RenderRequest request, RenderResponse response)
- throws Exception {
- Map<String, Object> model =
- new HashMap<String, Object>();
- model.put("helloWorldMessage", "Hello World");
- return new ModelAndView("helloWorld", model);
- }
- }
(4) 于是DispatcherPortlet找一个合适的视图来渲染页面,这时候,它委托ViewResolver 来解析包含在ModelAndView中的视图名"helloWorld",ViewResolver 根据以下portlet的Spring 配置文件:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans ... >
- ..
- <bean id="viewResolver"
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="viewClass"
- value="org.springframework.web.servlet.view.JstlView"/>
- <property name="prefix" value="/WEB-INF/jsp/" />
- <property name="suffix" value=".jsp" />
- </bean>
- </beans>
得知,一个叫 helloWorld的视图名会被映射到/WEB-INF/jsp/helloWorld.jsp的视图,它把最终解析得到的视图页面jsp信息连同模型Model信息返回给DispatcherPortlet
(5)最后到了渲染阶段,于是DispatcherPortlet 委托ViewRenderServlet ,让它基于helloWorld.jsp和模型数据进行渲染。ViewRenderServlet最终渲染到浏览器上。
- <web-app ...>
- ...
- <servlet>
- <servlet-name>ViewRendererServlet</servlet-name>
- <servlet-class>
- org.springframework.web.servlet.ViewRendererServlet
- </servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>ViewRendererServlet</servlet-name>
- <url-pattern>/WEB-INF/servlet/view</url-pattern>
- </servlet-mapping>
- ...
- </web-app>