使用 JSF、Ajax 和 Seam 开发 Portlets(2/3)

阅读数:1161 2008 年 11 月 27 日

第一部分中,我们介绍了 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 中文站用户讨论组参与我们的线上讨论。

收藏

评论

微博

发表评论

注册/登录 InfoQ 发表评论