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

在第一部分中,我们介绍了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了。

使用JSF、Ajax和Seam开发Portlets(2/3)_第1张图片

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版本中提供。

使用JSF、Ajax和Seam开发Portlets(2/3)_第2张图片

在论坛上发表反馈是十分有用和受欢迎的。如果想要了解JBoss Portlet Bridge项目的更多信息,请访问项目网站, 文档库或者wiki。

查看英文原文:Developing Portlets using JSF, Ajax, and Seam (Part 2 of 3)。

相关阅读:应用JSF、Ajax和Seam开发Portlets(1/3)。

志愿参与InfoQ中文站内容建设,请邮件至[email protected]。也欢迎大家到InfoQ中文站用户讨论组参与我们的线上讨论。

你可能感兴趣的:(使用JSF、Ajax和Seam开发Portlets(2/3))