Spring Portlet MVC 参考文档(中文版)

bb123

贡献于2014-11-04

字数:0 关键词: 门户平台Portal

WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net Spring Portlet MVC 参考文档 版本:0.9 版本修订历史记录: 版本 日期 修改内容 作者 0.9 2009-03 初次定稿 OliverChan linsapusic@gmail.com WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 目 录 1 引言 ..................................................................................................................................3 1.1 编者的话 ..........................................................................................................................3 1.2 面向读者 ..........................................................................................................................3 1.3 前提条件 ..........................................................................................................................3 2 Spring Portlet MVC..........................................................................................................3 2.1 介绍 ..................................................................................................................................3 2.1.1 控制器...............................................................................................................4 2.1.2 视图...................................................................................................................4 2.1.3 基于 Web 的 Bean............................................................................................4 2.2 DispatcherPortlet............................................................................................................4 2.3 ViewRendererServlet......................................................................................................6 2.4 控制器 ..............................................................................................................................7 2.4.1 AbstractController 和 PortletContentGenerator................................................8 2.4.2 其它的简单控制器...........................................................................................9 2.4.3 命令控制器.......................................................................................................9 2.4.4 PortletWrappingController..............................................................................10 2.5 处理器映射 ....................................................................................................................10 2.5.1 PortletModeHandlerMapping.........................................................................11 2.5.2 ParameterHandlerMapping.............................................................................11 2.5.3 PortletModeParameterHandlerMapping.........................................................12 2.5.4 增加 HandlerInterceptor.................................................................................13 2.5.5 HandlerInterceptorAdapter.............................................................................13 2.5.6 ParameterMappingInterceptor.........................................................................13 2.6 视图与解析 ....................................................................................................................13 2.7 多块(文件上传)支持 ................................................................................................14 2.7.1 使用 PortletMultipartResolver........................................................................14 2.7.2 在表单里上传文件处理.................................................................................15 2.8 处理异常 ........................................................................................................................18 2.9 Portlet 的应用部署........................................................................................................18 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 1 引言 1.1 编者的话 Spring Portlet MVC 是现在较少支持 Portlet 开发的框架之一,它不像 webwork2/Struts2 那样把 portlet 的处理转换成 servlet 支持。本文档是翻译 spring 参考文档的 16 章(版本 2.0.8), 讲述了 Spring Portlet MVC 概念及原理。特别到 Portlet MVC 框架里的一些相关概念与使用 的说明。这个文档有助于读者对其框架深入理解,灵活运用提供参考。由于本人的知识有限, 内容中难免存在有误内容,如果你对文档的内容有任何疑问和不同意见,欢迎跟我联系。关 于本人的 WP 最新资料请访问: http://www.webspherechina.net/?oliverchan,更多关于 websphere 的资料请访问:http://www.webspherechina.net。 1.2 面向读者 Portal 开发人员 1.3 前提条件 对 JSR-168 有原理,生命周期有了解,对 Spring 和 Spring Web MVC 有一定的了解。 2 Spring Portlet MVC 2.1 介绍 Spring 框架除了支持传统的 Web 应用开发外,还支持 JSR-168 的 portlet 应用开发。Spring Portlet MVC 是 Web MVC 的克隆,使用一样的抽象视图和整合技术。在继续后面内容前请 回顾十三章 Web MVC 框架和十四章整合视图技术。 Portlet 与 Servlet 生命周期最主要的区别在于 Portlet 的请求分为两个明显的阶段:行动 阶段和呈现阶段。行动阶段只执行一次是由于“后台”有改变或者行动发生,例如修改数据 库操作。呈现阶段是每次显示被刷新,然后产生显示结果给用户。这里的关键点是在单个全 生命周期的请求,行动阶段只被执行一次,但是呈现阶段可能执行多次。这样就使修改您系 统的持久状态的活动和产生显示给用户的活动有一个清晰的分离。 Portlet 两个阶段是 JSR-168 规范的一个功能强大的特性。例如,动态搜索显示结果可以 在显示修改而不需要用户重新运行搜索功能。很多其它的 portlet mvc 框架努力对开发人员 隐蔽两个阶段使 portlet 的开发尽可能像开发传统的 servlet 应用那样-我们认为这种方式减少 使用 portlet 的一个重要好处。所以 Spring 的 portlet mvc 框架是始终保留两个分离的阶段。 要记住的是虽然 Portlet MVC 和 Web MVC 的概念一样,但是要注意 portlet 独有的工作流。 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 这种方式的主要的表现是 servlet mvc 的版本的类有一个方法处理请求,portlet mvc 版本的 类有两个方法处理请求:一个是行动阶段和一个呈现阶段。例如,servlet 版本的 AbstractCo ntroller 有一个 handleRequestInternal(..)方法;portlet 版本的 AbstractController 有 handleActio nRequestInternal(..)和 handleRenderRequestInternal(..)方法。 这个框架围绕着一个分发请求到处理器的DispatcherPortlet设计,通过配置处理器映射与 视图决定的,就像web框架里的DispatcherServlet那样,文件上传也是这种方式支持。 Portlet MVC不支持本地化和主题决定-这些是Portal/Portlet-container支持的范围,不适 合在Spring容器的范围支持。然而所有依赖本地化(国际化和消息)的机制仍然是可用的功 能,因为DispatcherPortlet使用当前本地化像DispatcherServlet那样。 2.1.1 控制器 默认的处理器是一个非常简单的Controller接口,提供两个方法: void handleActionRequest(request,response) ModelAndView handleRenderRequest(request,response) 这个框架也包含很多跟servlet mvc一样层次的控制器实现,例如AbstractController, SimpleFormController等等。数据绑定,命令对象使用,模型处理和视图决定都和servlet mvc 一样。 2.1.2 视图 Servlet 框架的视图呈现能力是直接通过一个名为 ViewRendererServlet 的特殊 servlet 桥 来实现。使用这个 servlet 把 portlet 的请求转换成 servlet 的请求,完全使用 servlet 基础来呈 现视图。这就意味着现在现存的呈现,例如 JSP,Velocity 等等,仍可以在 portlet 里使用。 2.1.3 基于 Web 的 Bean Spring portlet mvc支持当前的在http请求或http会话Beans(常用的和全局的)范围bean的整个 生命周期。这个不是Portlet MVC自己独有的特性,而是Portlet MVC使用的 WebApplicationContext容器的。这些bean的范围细节描述请查阅Spring参考手册的3.4.4章。 2.2 DispatcherPortlet Portlet MVC 是一个请求驱动的 Web MVC 框架,围绕一个分发请求给控制器和提供其 它简化开发 portlet 程序功能的 portlet 设计。但是 DispatcherPortlet 所做的不止这些,它完全 与 Spring 的 ApplicationContext 整合在一起,使你可以使用 Sring 的其它特性。 像一般的 portlet 那样,DispatcherPortlet 在你的 Web 应用里的 portlet.xml 声明: WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net DispatcherPortlet 是必须配置的。 在 Portlet MVC 框架,每个 DispatcherPortlet 有自己的 WebApplicationContext,它继承 所有已经在根 WebApplicationContext 里定义的 bean。这些继承的 bean 能在具体的 portlet 里重载,新的 portlet bean 可以在具体的 portlet 的实例里定义。 在 DispatcherPortlet 初始化时,框架会在你的 web 应用的 WEB-INF 目录查找一个命名 为[portlet 名]-portlet.xml 的文件,创建定义的 bean(可以用相同的名字覆盖在全局范围的定 义 bean)。 DispatcherPortlet 使用的配置文件位置可以通过 portlet 的初始化参数修改(下面会 详细介绍)。 Spring 的 DispatcherPortlet 使用一些专门的 bean 处理请求和呈现适当的视图。这些 bean 包含在 Spring 框架里且能被配置到 WebApplicationContext,就像其它被配置的 bean 一样。 这些 bean 的每一个在下面更详细的描述。现在我们提及它们,只是为了让你知道它们的存 在且能让我们继续说明 DispatcherPortlet。对于大部分的这些 bean 是默认提供的,所以你不 必担心配置它们。 在 WebApplicationContex 专门的 bean 表达 说明 处理器映射 (章节 2.5 “处理器映射”)列表里的前置后置处理器和控 制器匹配某个标准将会被执行(例如一个匹配具体 portlet 模式的控制器)。 控制器 (章节 2.4 “控制器”)这些 bean 提供实际的功能(或 至少,访问功能性),是 MVC 模式中的控制器。 视图解析器 (章节 2.6 “视图与解析”)解析视图名对应的视图定义。 分块解析器 (章节 2.7 “分块(文件上传)支持”)提供从 HTML 表单上传文件的处理功能。 异常处理解析器 (章节 2.8 “异常处理”)提供异常映射到视图或其它复 杂的处理异常代码实现。 一旦 DispatcherPortlet 配置好,当请求进入具体的 DispatcherPortlet,它开始处理请求。下面 描述 DispatcherPortlet 处理请求的整个过程。 1. 通过 PortletRequest.getLocale()方法得到本地化的资源绑定到请求,当处理请求时能够解 析这些资源元素(呈现视图,准备数据等等)。 sample org.springframework.web.portlet.DispatcherPortle t text/html view Sample Portlet WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 2. 如果指定使用分块解析器,它是一个 ActionRequest,对请求进行多块检查,如果这些 块都能被找到就把它们封装在一个 MultipartActionRequest 里,以备在处理过程中被其 它元素作更深入的处理。(关于分块处理的详细信息参阅章节 2.7 “分块(文件上传) 支持”) 3. 查找适当的处理器。一旦找到处理器,控制器相关的执行链(前置,后置处理器和控制 器)将被执行来准备数据模型。 4. 如果返回模型,使用在 WebApplicationContex 配置的视图解析器呈现视图。如果没有数 据模型返回(可能因为前置或者后置处理器拦截请求,比如安全的原因),不 呈 现视图, 因为请求处理已经完成。 在处理请求时可能抛出异常。它 们 会 被 在 WebApplicationContex 配置里声明的任何异常解析 器获取。使用异常解析器你能定义定制处理异常抛出的行为。 增加在 portlet.xml 文件的上下文参数或 portlet 的初始化参数你能定制 Spring 的 DispatcherPortlet。参数列表如下: DispatcherPortlet 初始化参数 参数 描述 contextClass 这个类实现 WebApplicationContex,portlet 使 用它来初始化上下文,如果这个参数不设置, 则使用 XmlPortletApplicationContext。 contextConfigLocation 上下文实例(contextClass 指定)使用这个字 符串值找到上下文配置文件的位置。这个值 可以分割成多个字符串值(用逗号作分隔符) 以支持多个上下文配置文件(比如在多个上 下文配置文件存放位置情况下,一些 beans 被定义两次,后面的会替代前面的)。 namespace 在 WebApplicationContex 里的命令空间,默 认是{portlet 名}-portlet.xml。 viewRendererUrl DispatcherPortlet 访问 ViewRendererServlet 实 例的 URL。 2.3 ViewRendererServlet Portlet MVC 的呈现过程要比 Web MVC 复杂一点。为了重用 Spring Web MVC 所有的 视图技术,我们必须把 PortletRequest/PortletResponse 转换成 HttpServletRequest/HttpServlet Response,然后调用 view 的 render 方法。为了实现上述目的,DispatcherPortlet 使用已经存 专用的 servlet 类:ViewRendererServlet。 为了让 DispatcherPortlet 能执行呈现工作,你必须在你的 web 项目的 web.xm 像下面那 样声明 ViewRendererServlet 的实例。 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 执行实际的呈现,DispatcherPortlet 的工作过程如下: 1. 把 WebApplicationContex 绑定到 request 的一个属性里,这个属性是 DispatcherPortlet 使 用主键 WEB_APPLICATION_CONTEXT_ATTRIBUTE 储存的。 2. 绑定模型和视图对象到 request 里,使 ViewRendererServlet 能够获取它们。 3. 构造一个 PortletRequestDispatcher 对象,用映射到 ViewRendererServlet 的/WEB- INF/servlet/view URL 执行一个 include。 ViewRendererServlet 然后使用合适的参数调用视图的 render 方法。 通过配置 DispatcherPortlet的 viewRendererUrl参数可以修改 ViewRendererServlet 所使用的具 体 URL。 2.4 控制器 Portlet MVC 的控制器与 Web MVC 的控制器十分相似,它们互相转换修改的代码非常 简单。Portlet MVC 的控制器架构的基础是 org.springframework.web.portlet.mvc.Controller 接 口,如下面所示: 正如你所看到的,Portlet 的控制器接口的两个方法处理 portlet 两个阶段的请求:行动阶 段请求与呈现阶段请求。行动阶段能够处理行动的请求而呈现阶段能处理呈现阶段的请求和 返回适当的模型与视图。Controller 接口十分抽象,Spring Portlet MVC 提供你可能需要的已 经实现的包含很多功能的控制器-这些控制器很大程度与 Spring Web MVC 相似。Controller 接口仅是定义了所有控制器最通用且必须的功能-处理行动请求,处理贵请求和返回模型与 视图。 public interface Controller { /** * Process the render request and return a ModelAndView object which the * DispatcherPortlet will render. */ ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception; /** * Process the action request. There is nothing to return. */ void handleActionRequest(ActionRequest request, ActionResponse response) throws Exception; } ViewRendererServlet org.springframework.web.servlet.ViewRendererServlet ViewRendererServlet /WEB-INF/servlet/view WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 2.4.1 AbstractController 和 PortletContentGenerator 当然,仅仅是一个 Controller 接口是不够的。为了提供一个基础架构,所有 Spring Portlet MVC 的控制器都继承 AbstractController,这是一个访问 Spring 的 WebApplicationContex 和 控制缓存的类。 AbstractController 提供的特性 参数 说明 requireSession 指定这个控制器是否需要一个回话运行。所 有的控制器都使用这个特性。如果没有会话, 会抛出一个 SessionRequiredException 异常给 用户。 synchronizeSession 如果你想处理控制器同步用户会话信息,使 用这个参数。这个扩展的控制器要重载 handleRenderRequestInternal(..) 和 handleActionRequestInternal(..)方法,如果你指 定这个变量,这个类会同步用户回话信息。 renderWhenMinimized 当你想控制器在 portlet 最小状态呈现,把这 个值设置为 true。在默认情况下,这个值是 false 因而 portlet 在最小状态是不呈现任何内 容。 cacheSeconds 当你想控制器重载默认的缓存存活期,把这 个值设置为正整数。默认值为-1 说明不修改 默认的缓存存活期,设置为 0 说明不作缓存。 在PortletContentGenerator类声明requireSession和cacheSeconds属性,它是 AbstractController的超类,在这里为了内容的完整说明一下。 当你的控制器用AbstractController用基类(不推荐,因为现存的很多控制器可能已经实 现了你要的功能)你必须重载handleActionRequestInternal(ActionRequest, ActionResponse)方 法或handleRenderRequestInternal(RenderRequest, RenderResponse)方法(或两个方法), 实 现 你 的 逻辑,然后返回一个ModelAndView对象(在handleRenderRequestInternal方法)。 handleActionRequestInternal(..)和handleRenderRequestInternal(..)两个方法的实现都是抛 PortletException异常。 这个与JSR-168规范里GenericPortletr的API一致。所以你只须重载方法去实现你定制的 处理。 在这里有一个简单类和web应用环境的声明组成的例子。 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 除了设置处理器映射外(请参阅 2.5“处理器映射”),上面的类和声明是使这个简单的控 制器运行起来所需要的。 2.4.2 其它的简单控制器 尽管你能扩展 AbstractController 类,但 Spring Portlet MVC 提供很多已经实现了的通用 功能的控制器。 除 了 可以设置返回在 Web 应用环境的视图(不需要用硬编码返回视图), ParameterizableViewController 是和上面例子一样基础的控制器。 PortletModeNameViewController 使当前 Portlet 的模型作为视图名。因此,如果你的 Portlet 是在 VIEW 模式(例如 PortletMode.VIEW)它使用“view“作为视图名。 2.4.3 命令控制器 Spring Portlet MVC 有跟 Spring Web MVC 一样层次命令控制器,这些控制器提供了与 数据对象交互和动态把 PortletRequest 的参数绑定到指定的数据对象的途径。你的数据模型 不需要实现框架的特定接口,所以你可以随意操作你的持久对象。 让我们来看一下可以获 取的命令控制器,作概要介绍,以便你使用: AbstractCommandController-你可以使用这个控制器来创建你自己的控制器,它能够设 置请求里的参数绑定具体的数据对象。这个类不提供表单功能,但是提供校验特性和让你设 置请求参数填充命令对象。 AbstractFormController-一个支持表单提交的抽象控制器。使用这个控制器模型化表单 及在控制器里操作得到的命令对象。在用户填充表单后,AbstractFormController 绑定所有的 字段,校验,和传送后台对象到控制器分发到适当的行动。支持的特性:提交非法表单(重 提交), 校验,和一般的表单流程。你可以实现方法决定使用表单的视图与成功后跳转视图。 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; } } WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 如果你需要表单提交可以使用这个控制器,但是你不能在应用的上下文里指定跳转的视图 (跳转的视图只能是硬编码的视图,不能是配置指定的视图)。 SimpleFormController-AbstractFormController 的一个具体类,当创建与命令对象相应的 表单,它提供更多的支持。SimpleFormController 让你指定一个命令对象,表单的视图名, 当表单成功提交后显示给用户的页面视图名,或更多配置信息。 AbstractWizardFormController-AbstractFormController 的一个具体类,它为编辑跨多页 面的命令对象的内容提供一种向导样式的接口。支持多个行动:完成,取消,或改变页面, 指定在视图的请求参数很容易使用上述这些功能。 这些命令控制器功能十分强大,但是为了有效的使用这些控制器则要求对它们的操作有 比较深入的了解。在你开始使用它们前仔细参阅 JavaDoc 的全部层次和一些例子的实现。 2.4.4 PortletWrappingController 不开发新的控制器,可能使用现存的 portlet 和从 DispatcherPortlet 映射请求到这些 portlet。使用 PortletWrappingController 你能初始化一个现存的 Portlet 作为一个控制器像下面 这样: 这样做是相当有价值的,因为这样你就能在请求进入这些portlet的时候使用拦截器做前置处 理和后置处理。因为JSR-168不支持任何类型的过滤器机制,这样做相当便利。例如,这样 就能用Hibernate的OpenSessionInViewInterceptor包装一个MyFaces JSF Portlet。 2.5 处理器映射 使用处理器映射,你能把进入Portlet的请求映射到适当的处理器。在 容 器里你可以使用一 些现存的处理器映射,比如PortletModeHandlerMapping,让我们先看一下HandlerMapping的 概念。 HandlerMapping基本的作用是给HandlerExecutionChain提供传输功能,它一定包含匹配 处理进入的请求的处理器,也可能是应用于请求的一系列作处理的拦截器。当一个请求进入, config=/WEB-INF/my-portlet-config.xml 注:我们有意用名词“处理器”代替“控制器”。 DispatcherPortlet 是设计用来处理其它方式的请求, 而不只是 Spring Portlet MVC 自个的控制器。处理器是能处理 Portlet 请求的任何一个对象。控制器是 处理器的一个例子,且是默认的。用 DispatcherPortlet 与其它框架一起使用,必须使用 HandlerAdapter 接口的实现类来通信。 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net DispatcherPortlet就把请求传给处理器映射,让它检查并把请求交给适当的 HandlerExecutionChain处理。然后DispatcherPortlet执行处理链的处理器与拦截器。这些概念 和Spring Web MVC一样。 配置处理器映射的概念是能够包含任意的拦截器( 前 置 处理器执行,或后置处理器执行, 或两者都有),它的功能十分强大。创建定制的 HandlerMapping 能支持更多内建的功能。定 制的处理器映射不但可以根据 portlet 的模式的请求选择处理器,也可以根据请求相关的会 话状态选择处理器。 在 Spring Web MVC,处理器映射通常依赖 URL。因为 Portlet 里没有像 URL 这样的东 西,我们必须使用其它机制来控制映射。Portlet 模式和请求参数是常用的两个方法,但是在 Portlet 的请求里任何可得到的参数都可以在定制的处理器映射里使用。 后面的章节描述三个Spring Portlet MVC常用的处理器映射。它们都继承 AbstractHandlerMapping和共享下面属性: interceptors:使用的拦截器列表。HandlerInterceptors在章节 16.5.4“增加HandlerInterceptors” 里讨论。 defaultHandler: 当处理器映射没有找到匹配的处理器,使用的默认处理器。 order: 基于次序属性的值(参阅org.springframework.core.Ordered接口), Spring把在上下文 能获取到的处理器映射排序且应用于第一个匹配的处理器。 lazyInitHandlers:允许单例处理器延迟加载(原型的处理器通常是延迟加载)。 默认的值是 false。这个属性三个具体的处理器都实现。 2.5.1 PortletModeHandlerMapping 这个简单的处理器映射就是根据当前 Portlet 的模式映射进入的请求(‘view’,‘edit’, ‘help’等等)。一个例子: 2.5.2 ParameterHandlerMapping 如果在不改变 Portlet 模式条件下,需要跳转到不同的控制器,最简单的方法就是用请 求参数作为主键控制映射。 ParameterHandlerMapping 使用指定的请求参数值控制映射。默认的参数名是“action“, 但改变通过修改“parameterName”属性可以更改。 这个映射 bean 的配置看起来像这样: WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 2.5.3 PortletModeParameterHandlerMapping 功能最强大的内建处理种器映射 PortletModeParameterHandlerMapping 结合了上面提及 的两种处理器映射允许在每个 Portlet 模式里跳转不同的控制器。 同样默认的参数名是“action”,但是通过使用“parameterName”属性能够改变。 在默认的情况下,同样的参数值不可以在两个不同的 Portlet 模式使用。所以如果门户 自己改变了 Portlet 的模式,请求不再是合法映射。通过设置 allowDupParameters 属性为 true 可以改变这种情况。然而这是不推荐的。 这个映射 bean 的配置看起来像这样: 这个映射是以PortletModeHandlerMapping作为映射链的入口,它能提供到每个portlet模式的 默认映射。 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 2.5.4 增加 HandlerInterceptor Spring 的处理器映射机制有一个处理拦截器概念,当你想把特定的功能应用于某个请 求,处理拦截器相当有用,比如检查凭证。重提一下 Spring Portlet MVC 跟 Web MVC 一样 实现这些概念。 位于处理器映射里的拦截器必须要实现 org.springframework.web.portlet 包的 HandlerInterceptor 接口。跟 Servlet 版本一样,这个接口定义了三个方法:一是在实际的处 理器执行之前调用(preHandle),一个是处理器执行后调用(postHandle),一个是请求完全 完成后调用(afterCompletion)。这三个方法提供足够的弹性做各种前置和后置处理。 preHandle 方法返回一个布尔值。你可以使用这个方法中断或者继续执行链的处理。当 这个方法返回 true,这个处理执行链继续。当返回 false,DispatcherPortlet 假定这个拦截器 已经处理完请求(比如呈现适当的视图), 然 后 不 再 继续执行其它的拦截器和执行链里的处 理器。 postHandle 方法只被 RenderRequest 调用。preHandle 与 afterCompletion 方法都可以在 ActionRequest 和 RenderRequest 被调用。如果你需要对应一种类型请求在这些方法里执行逻 辑,确定这个类型请求在你的业务逻辑前处理。 2.5.5 HandlerInterceptorAdapter 和servlet的包一样,portlet的包有HandlerInterceptor接口的具体实现是 HandlerInterceptorAdapter。这个类所有方法是空的,因此你可以继承它实现你需要的一个或 两个方法。 2.5.6 ParameterMappingInterceptor Portlet包也有一个具体的拦截器ParameterMappingInterceptor,这就意味着可以直接被 ParameterHandlerMapping和PortletModeParameterHandlerMapping使用。这个拦截器将形成用 于控制从ActionRequest到RenderRequest映射的参数。这个有助于确认RenderRequest被映射 到如同ActionRequest一样的处理器。这过程在拦截器里的preHandle方法完成,所以你仍然 可以在处理器修改参数值改变映射的RenderRequest。 要明确的是这个拦截器是调用在ActionReponse里setRenderParameter方法,这就意味着 当你使用拦截器时你的处理器不能调用sendRedirect方法。如果你想要做额外的跳转,得手 动设置前进的映射参数或编写不同的拦截器来为你处理这个。 2.6 视图与解析 如上面所述,Spring Portlet MVC直接重用所有Spring Web MVC的视图技术。这些视图 不只是各种View的实现,还有ViewResolver的实现。更多的信息,参考14章和13.5节内容。 下面谈一些使用现存的View和ViewResolver实现有用的内容点: 大部分门户希望Portlet呈现是HTML片段。所以像JSP/JSTL,Velocity,FreeMaker,和XSLT 这些仍然可用。但是其它类型文档的视图是不可用的。 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net Portlet里没有HTTP的跳转(ActionResponse的sendRedirect(..)仍在门户里存在,但不起 作用)。 因 此 , RedirectView和使用“redirect”前缀在Portlet MVC不起作用。 在Portlet MVC里可能使用“forward”前缀。然而强调的是你是在portlet里,是完全不知 道似当前URL的链接。这就是意味着不能在你的Web应用里使用相对URL访问其它资源,只 能使用绝对URL。 同时,对于JSP开发,新的Spring标签和新的Spring表单标签都可以在Portlet的视图里使 用,这个跟Servlet一样。 2.7 多块(文件上传)支持 Spring Portlet MVC有内建的多块支持在Portlet应用里处理文件上传,就像Web MVC那 样。多块支持的设计是可插入方式,要插入在org.springframework.web.portlet.multipart包定 义的PortletMultipartResolver对象。Spring提供一个使用Commons文件上传 PortletMultipartResolver。如何支持文件上传将下面章节描述。 在默认情况下,Spring Portlet MVC不作分块处理,因为一些开发者希望自己作分块处 理。你只得自己开启这个功能通过在应用上下文增加多块处理器。在开启后,DispatcherPortlet 检查每个请求是否包含多块。如果没有找到多块,请求还是按原定的那样执行。如果在请求 里找到一个多块,在你上下文声明的PortletMultipartResolver将会被使用。一旦完成上述的, 请求里的多块属性的处理就如其它属性一样。 2.7.1 使用 PortletMultipartResolver 下面的例子是显示如何使用CommonsPortletMultipartResolver: 当然你还要把适当的jar包放在你的classpath下多块解析器才能运行起来。使用 CommonsPortletMultipartResolver,你必须使用commons-fileupload.jar。确认使用的版本至少 是1.1的Commons文件上传,低于这个版本不支持JSR-168 Portlet应用程序。 现在你已经看到如何设置Portlet MVC使用多块请求,让我们继续讨论如何在实际中应 用。当DispatcherPortlet在请求里检查到一个多块,它 激 活 在 你 上 下 文 声 明的解析器来处理这 个请求。然后解析器把当前的ActionRequest封装成支持多块文件上传的 MultipartActionRequest。使用MultipartActionRequest你能在控制器取得当前请求里包含的多 块信息和能够访问这些多块文件。 记住你只有把收到的上传的多块的文件作为ActionRequest的部分,而不是 RenderRequest的部分。 注:任何配置PortletMultipartResolver的bean名或id必须为:“ portletMultipartResolver“。如果你是 把PortletMultipartResolver配置为其它名,DispatcherPortlet不能找到你的PortletMultipartResolver, 结果配置多块支持无效。 WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 2.7.2 在表单里上传文件处理 在PortletMultipartResolver完成它的工作后,包含多块的请求像其它请求一样处理。为了 使用它,你用一个上传字段建立一个表单(查看下面)。 然 后 让 Spring用这个文件绑定你的 表单(后台对象)。 实际上,让用户上传文件,我们得先创建一个(JSP/HTML)表单: 正如你所看到的,我们创建一个字段命名为“file”,然后bean的这个属性为byte[]类型。 而且我们增加编码属性(enctype="multipart/form-data"),这样做就是让浏览器知道如何编码 多块字段(不要忘记这个)。 像其它属性那样不会自动转换成字符或原始类型,用PortletRequestDataBinder注册定制 编辑器就能在你的对象里放置二进制数据。这里可以获得几个编辑器在对象里处理文件和设 置结果。StringMultipartFileEditor能够把文件转换成字符串对象(使用用户自定义的字符集), ByteArrayMultipartFileEditor把文件转换成二进制数组。它们的功能正是CustomDateEditor所 做的那样。 因此,为了上传文件使用一个表单,声明解析器,映射一个能处理bean的控制器。 然后,创建一个控制器和包含文件属性的类。

Please upload a file

WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 正如你所看到的,FileUploadBean有一个保存文件的byte[]类型的属性。这个控制器注册 一个定制的编辑器,让Spring知道在实际中如何把解析器找到的多块对象转换成bean指定的 属性。在这个例子里,bean没有对byte[]属性做任何事情,但是实际上你可以做你想要的( 保 存 这个属性到数据库,给某人发邮件等等)。 在一个差不多相同的例子,一个文件被绑定到一个对象(后台对象)的 字 符串类型属性, 代码如下: public class FileUploadController extends SimpleFormController { public void onSubmitAction( ActionRequest request, ActionResponse response, Object command, BindException errors) throws Exception { // cast the bean FileUploadBean bean = (FileUploadBean) command; // let's see if there's content there byte[] file = bean.getFile(); if (file == null) { // hmm, that's strange, the user did not upload anything } // do something with the file here } protected void initBinder( PortletRequest request, PortletRequestDataBinder binder) throws Exception { // to actually be able to convert Multipart instance to byte[] // we have to register a custom editor binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor()); // now Spring knows how to handle multipart object and convert } } public class FileUploadBean { private byte[] file; public void setFile(byte[] file) { this.file = file; } public byte[] getFile() { return file; } } WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 当然,上面的例子只有在上下文上传文本文件有效(对于上传图像文件的情况不起作用)。 第 三 个(最后)选择是直接绑定一个MultipartFile到对象(后台)类里声明的属性。在 这种情况下不必要注册任何定制属性编辑器因为没有任何类型转换。 public class FileUploadController extends SimpleFormController { public void onSubmitAction( ActionRequest request, ActionResponse response, Object command, BindException errors) throws Exception { // cast the bean FileUploadBean bean = (FileUploadBean) command; // let's see if there's content there String file = bean.getFile(); if (file == null) { // hmm, that's strange, the user did not upload anything } // do something with the file here } protected void initBinder( PortletRequest request, PortletRequestDataBinder binder) throws Exception { // to actually be able to convert Multipart instance to a String // we have to register a custom editor binder.registerCustomEditor(String.class, new StringMultipartFileEditor()); // now Spring knows how to handle multipart objects and convert } } public class FileUploadBean { private String file; public void setFile(String file) { this.file = file; } public String getFile() { return file; } } WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net 2.8 处理异常 像Web MVC一样,Portlet MVC提供HandleExceptionResolver减轻在处理器处理请求时发 生的不可预见的异常痛苦。Portlet MVC也提供一样的SimpleMappingExceptionResolver实现, 它使你能把类抛出的任何异常映射一个视图名。 2.9 Portlet 的应用部署 部署Spring Portlet MVC应用过程跟部署任何JSR-168应用的过程一样。一般来说,这个 地方容易混淆在这里简要说明一下。 一般来说,Portal/Portlet-container是在servlvet容器里的web应用里运行,你的Portlet是在 你的servlet容器其它应用里。为了让portlet-container应用访问portlet应用,必须要跨上下文调 用一个访问portlet.xml文件定义Portlet服务的servlet。 JSR-168没有具体指定这个过程,因而每个portlet-container有它自己的机制实现它,这 包括在portlet应用作一些修改和把porlet注册到portlet-container的一些部署过程。 在最小化的情况,在你portlet应用的web.xml文件被修改过注入到servlet容器,这样 public class FileUploadController extends SimpleFormController { public void onSubmitAction( ActionRequest request, ActionResponse response, Object command, BindException errors) throws Exception { // cast the bean FileUploadBean bean = (FileUploadBean) command; // let's see if there's content there MultipartFile file = bean.getFile(); if (file == null) { // hmm, that's strange, the user did not upload anything } // do something with the file here } } public class FileUploadBean { private MultipartFile file; public void setFile(MultipartFile file) { this.file = file; } public MultipartFile getFile() { return file; } } WebSphere 开发应用社区 http://www.webspherechina.net —————————————————————————————————————————————— WebSphere 开发应用社区 http://www.webspherechina.net portlet-container就能调用。在一些情况下,在web应用中单个servle服务所有的portlet,而其 它的情况则是每个portlet一个servlet实例。 一些portlet-container也注入类库和配置文件到web应用,portlet-container一定要做到 Portlet JSP标签的实现让你的web应用获得。 简短的说理解部署你的目的portal和确定它们的情况是很重要的(一般来说它是支持自 动部署的)。 仔 细查看你的portal的部署过程文档。 一旦你已经部署你的portlet,仔细查看结果的web.xml。一些旧的portal会破坏 ViewRendererServlet定义,因此断开你的portlet的呈现。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档

相关文档