在第一部分中,我们介绍了JSF portlet 运行的基础知识,包括工程创建、三个基本的XML 配置文件和一些通用的JSF Portlet 开发人员经常遇到的问题和解答。现在,我会讲解如何通过 RichFaces 组件库使用 AJAX 来增强你的 JSF portlet。
工程搭建
开发工具:
为了与本文保持一致,请下载最新版本的 Maven(我使用 2.0.9)。
安装 Maven 2.0.9 或更高版本
设置 Maven 系统环境变量
范例中使用的服务器和二进制执行文件:
JBoss Portal 2.7 Beta1
JBoss Portlet Bridge Beta3
在本文第一部分中,我曾解释过 Maven archetypes 的用法,以及你想要
<context-param> <param-name>org.richfaces.LoadStyleStrategy</param-name> <param-value>NONE</param-value> </context-param> <context-param> <param-name>org.richfaces.LoadScriptStrategy</param-name> <param-value>NONE</param-value> </context-param> <context-param> <param-name>org.ajax4jsf.RESOURCE_URI_PREFIX</param-name> <param-value>rfRes</param-value> </context-param> <filter> <display-name>Ajax4jsf Filter</display-name> <filter-name>ajax4jsf</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>ajax4jsf</filter-name> <servlet-name>FacesServlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
搭建的工程是如何自动部署到运行着 JBoss Portal 的 JBoss 应用服务器上的。为了便于使用,第二部分的前几节与第一部分是相同的。唯一的修改是工程名字——所有的 Maven 命令保持不变。一旦你的 RichFaces 创建成功,你会获得一个实引用和测试环境来尝试下面的代码示例。
现在让我们生成 RichFaces 工程、检查源代码和快速学习一下配置。最后,我们将运行 demo,并研究一些真实世界的开发任务。
启动一个终端并运行以下命令:
mvn archetype:generate -DarchetypeGroupId=org.jboss.portletbridge.archetypes -DarchetypeArtifactId=richfaces-basic -DarchetypeVersion=1.0.0.B3 -DgroupId=org.my.project -DartifactId=richfacesproject -DarchetypeRepository=http://repository.jboss.org/maven2/ -Dversion=1.0.0.B3
打开工程所在目录,如果你使用以上命令,目录名应该是“richfacesproject”。简单浏览一下目录的文件结构,你会看到 Maven 文件夹下本示例的源代码。现在你可以启动你喜欢的 IDE 并导入 Maven 工程了。
配置
使用 RichFaces 库的任何组件前,必须对 XML 文件做一下小改动。这些设置只是对第一部分中原来的配置的一些扩展,所以我在这里只提及针对JBoss Portlet Bridge 的JSF 相关的配置。下面的设置请根据您个人的需要选择。为了使本文的重点集中于AJAX portlet 开发,我只会简单介绍一下这些选项如何影响你的portlet。更多信息请查看RichFaces 文档的相关章节。
web.xml
--------------
本文件可以控制用于显示 RichFaces 的脚本和 CSS 样式表。对于 JBoss Portal,我们可以关闭样式表和脚本的加载,这样它们在 portal 页面头部只会加载一次:
<context-param> <param-name>org.richfaces.LoadStyleStrategy</param-name> <param-value>NONE</param-value> </context-param> <context-param> <param-name>org.richfaces.LoadScriptStrategy</param-name> <param-value>NONE</param-value> </context-param> <context-param> <param-name>org.ajax4jsf.RESOURCE_URI_PREFIX</param-name> <param-value>rfRes</param-value> </context-param> <filter> <display-name>Ajax4jsf Filter</display-name> <filter-name>ajax4jsf</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>ajax4jsf</filter-name> <servlet-name>FacesServlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
jboss-portlet.xml
--------------
在这里你可以指定在 portal 页面头部会加载哪些内容。正如你所看到的,“rfRes”在 web.xml 中被设为 RESOURCE_URI_PREFIX。下一步是插入 servlet_path/RESOURCE_URI_PREFIX 来访问通过 classpath 获取的 RichFaces 资源。
还需要配置三个文件以正确显示和使用 RichFaces 组件包:
<portlet> <portlet-name>ajaxPortlet</portlet-name> <header-content> <script src="/faces/rfRes/org/ajax4jsf/framework.pack.js" type="text/javascript"></script> <script src="/faces/rfRes/org/richfaces/ui.pack.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="/faces/rfRes/org/richfaces/skin.xcss"/> </header-content> </portlet>
运行 Demo
现在我们启动服务器并通过两个简单的命令部署你的 RichFaces portlet。在开始之前,我想指出在 JBoss Portal 安装上,本文和第一部分的区别。在上一期文章中,我们是部署到可以运行轻量级的 Portlet Container 2.0 示例的 JBoss 应用服务器上。上期文章发表以后,JBoss Portal 2.7 beta 版发布。它融合了 JBoss Portal 旧的 JSR-168 实现和新的 Portlet 2.0 实现,使我们能够在标准的 JBoss Portal 工程中同时运行 1.0 和 2.0 portlets。所以请不要对你应该使用哪个版本感到困惑。只要记住 JBoss Portal 2.7 包含了我们需要的一切内容,而 2.6.x 版本是支持 JSR-168 (portlet 1.0) 的稳定版本即可。
更多关于部署本 demo portlet 到 JBoss Portal 各种版本(beta 或稳定版)的信息,请阅读这里。
第一步:下载并启动服务器
从 http://downloads.sourceforge.net/jboss/jboss-portal-2.7.0.B1-bundled.zip 下载集成了 JBoss Portal 2.7 Beta1 的 JBoss 应用服务器。然后将下列命令中的 path_to_bundle_zip 以 JBoss Portal 2.7 的绝对路径替换并运行:
mvn install cargo:start -Plocal-portal -DJBOSS_ZIP_HOME=/path_to_bundle_zip/jboss- portal-2.7.0.B1-bundled.zip -DJBOSS_HOME_DIR=jboss-portal-2.7.0.B1- bundled/jboss-portal-2.7.0.B1
该命令有点长,不过可以让你打包任何兼容的 JBoss App Server 和 JBoss Portal 版本。
如果你看到下列输出,则可以进行下一步了:
第二步:部署demo 应用
现在打开另一个终端窗口,进入“ richfacesproject
”根目录,运行下列命令:
mvn cargo:deploy -Plocal-portal -DJBOSS_ZIP_HOME=/path_to_bundle_zip/jboss- portal-2.7.0.B1-bundled.zip -DJBOSS_HOME_DIR=jboss-portal-2.7.0.B1-bundled/jboss- portal-2.7.0.B1
不要忘记把“path_to_bundle_zip”替换成正确的路径。
现在你可以通过 http://localhost:8080/portal/portal/default/RichFacesEchoPortlet 访问 RichFaces demo portlet 了。
RichFaces Portlet 开发
当通过 portlet 进行 AJAX 请求时,必须明白 portlet 和 servlet 在 session 之间的区别。例如,当用户在 portlet 内部使用 AJAX 请求时,这是通过原始的 HTTP session 实现的,请求无法访问存储在 portal session 中的对象。针对这个问题,我们实现了一种方法来允许我们访问 Portal session 属性。它们通过窗口 ID 来区别作用域,例如,如果 Portlet 在 session 中存储值“YourObject”,那么就可以通过 “javax.portlet.p.XYZ?YourObject”来访问,其中 XYZ 是窗口 ID。
你可以通过以下命令从 UI 中获取 windowID 或者 scopeID:
#{facesContext.externalContext.sessionMap['org.jboss.portletbridge.WINDOW_ID_RETRIVER'].windowID} #{facesContext.externalContext.sessionMap['org.jboss.portletbridge.WINDOW_ID_RETRIVER'].scopeId}
正如你看到的,facesContext.externalContext.sessionMap
指向的是 portlet 作用域内的 session 对象。为什么你会需要使用到这些值呢?下面列举到了一些你可能会遇到的情况:
- 当你在 AJAX 请求时需要来自 portal session 的认证数据时
- 动态资源生成时(图片、脚本等等)
其他例子
整个 RichFaces 库都可以通过一个运行的 demo 看到,源代码可以在这里下载。如果你对组件配置不确定或者你认为无法在portal 环境中运行,那么本工程对你非常有帮助。这个demo 中唯一缺少的组件是文件上传组件。该组件计划在九月初的下一个porlet bridge 版本中提供。
在论坛上发表反馈是十分有用和受欢迎的。如果想要了解JBoss Portlet Bridge 项目的更多信息,请访问项目网站, 文档库或者 wiki 。
查看英文原文: Developing Portlets using JSF, Ajax, and Seam (Part 2 of 3) 。
相关阅读:应用JSF、Ajax 和Seam 开发Portlets(1/3)。
志愿参与InfoQ 中文站内容建设,请邮件至 editors@cn.infoq.com 。也欢迎大家到 InfoQ 中文站用户讨论组参与我们的线上讨论。
评论