如上所示,这是Spring Portlet MVC的整个工作流程:

DispatcherPortlet 作为前端控制器,负责接收所有到Portlet的请求

(1) 当Portlet请求发送到DispatcherPortlet时,它利用PortletMVC的HandlerMapping来找到一个合适的Handler(也就是controller)来处理当前请求

 
  
  1. <portlet> 
  2. <portlet-name>helloWorld</portlet-name> 
  3. <portlet-class> 
  4. org.springframework.web.portlet.DispatcherPortlet 
  5. </portlet-class> 
  6. <supports> 
  7. <mime-type>text/html</mime-type> 
  8. <portlet-mode>view</portlet-mode> 
  9. </supports> 
  10. <resource-bundle>content.Language-ext</resource-bundle> 
  11. <portlet-info> 
  12. <title>HelloWorld</title> 
  13. </portlet-info> 
  14. </portlet> 

(2) PortletMVC 提供了一个PortletModeHandlerMapping,它实现了HandlerMapping接口,并且它基于当前Portlet的模式(view/edit/help....)来选择恰当的Handler.这个模式->Handler的映射规则配置在 <portlet-name>-portlet.xml ,它是该portlet的Spring配置文件

比如:

 
  
  1. <beans ... > 
  2. <bean id="helloWorldController" 
  3. class="chapter07.code.listing.HelloWorldController"/> 
  4.  
  5. <bean id="portletModeHandlerMapping" 
  6. class="org.springframework.web.portlet.handler.PortletModeHandlerMapping"> 
  7. <property name="portletModeMap"> 
  8. <map> 
  9. <entry key="view"> 
  10. <ref bean="helloWorldController" /> 
  11. </entry> 
  12. </map> 
  13. </property> 
  14. </bean> 
  15.  
  16. </beans> 

在这个例子中,我们可以看到PortletModeHandlerMapping将view模式匹配到了HelloWorldController 作为Handler,所以这个HellowWorldController有能力处理render类型的请求(对应view模式)

(3) 于是,这个DispatcherPortlet会指派HelloWorldController,而HelloWorldController处理了render类型的请求,然后返回一个ModelAndView对象给DispatcherPortlet.

 
  
  1. public class HelloWorldController implements Controller{ 
  2. public void handleActionRequest(ActionRequest request, 
  3. ActionResponse response)throws Exception { 
  4. //这个是render类型请求的处理函数,请求结果被封装在ModelAndView对象中返回给调用者,也就是返回给DispatcherPortlet
  5. public ModelAndView handleRenderRequest 
  6. (RenderRequest request, RenderResponse response) 
  7. throws Exception { 
  8. Map<String, Object> model = 
  9. new HashMap<String, Object>(); 
  10. model.put("helloWorldMessage""Hello World"); 
  11. return new ModelAndView("helloWorld", model); 

 

(4) 于是DispatcherPortlet找一个合适的视图来渲染页面,这时候,它委托ViewResolver 来解析包含在ModelAndView中的视图名"helloWorld",ViewResolver 根据以下portlet的Spring 配置文件:

 
  
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <beans ... > 
  3. .. 
  4. <bean id="viewResolver" 
  5. class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
  6. <property name="viewClass" 
  7. value="org.springframework.web.servlet.view.JstlView"/> 
  8. <property name="prefix" value="/WEB-INF/jsp/" /> 
  9. <property name="suffix" value=".jsp" /> 
  10. </bean> 
  11. </beans> 

得知,一个叫 helloWorld的视图名会被映射到/WEB-INF/jsp/helloWorld.jsp的视图,它把最终解析得到的视图页面jsp信息连同模型Model信息返回给DispatcherPortlet

 

(5)最后到了渲染阶段,于是DispatcherPortlet 委托ViewRenderServlet ,让它基于helloWorld.jsp和模型数据进行渲染。ViewRenderServlet最终渲染到浏览器上。

 
  
  1. <web-app ...> 
  2. ... 
  3. <servlet> 
  4. <servlet-name>ViewRendererServlet</servlet-name> 
  5. <servlet-class> 
  6. org.springframework.web.servlet.ViewRendererServlet 
  7. </servlet-class> 
  8. </servlet> 
  9. <servlet-mapping> 
  10. <servlet-name>ViewRendererServlet</servlet-name> 
  11. <url-pattern>/WEB-INF/servlet/view</url-pattern> 
  12. </servlet-mapping> 
  13. ... 
  14. </web-app>