大厂Data+Agent 秘籍:腾讯/阿里/字节解析如何提升数据分析智能。 了解详情
写点什么

应用 JSF、Ajax 和 Seam 开发 Portlets(1/3)

  • 2008-11-13
  • 本文字数:4087 字

    阅读完需:约 13 分钟

如果你刚开始考虑应用 portal 解决方案,或者想了解把一个新的或现有的 JSF 应用整合进一个 portal 环境有多容易,那么本文绝对值得你仔细研读。

在过去几年中,portals 无论是在企业还是在增强的 portlet 2.0( JSR 286 )规范中都得到了长足发展。新 2.0 版本的 portlets 在聚合不同的应用,并将其呈现在同一个页面的不同窗口方面赋于开发人员很大的自由。此外,它还提供了认证功能,成熟的个性化特性和更好的处理 AJAX 的现成方法。

JSR 301 portlet 桥接规范(portlet bridge specification)的出现,使我们具备了运行 JSF 应用的标准方式,不论 portlets 版本是 1.0 还是 2.0。portlet 桥(bridge)可以支配 portal 的 Action/Render 范式适当地处理 JSF 的生命周期。本教程将主要向你展示配置与开发 JSF portlet 是多么容易的一件事情,同时还会介绍新的 JBoss Portlet Container 2.0 及其一些很酷的新特性。

本文是由三部分组成的系列文章的第一篇。该系列文章从基本的 JSF portlet 和 portal 知识一直讲到 portlet 环境中的 AJAX 和 Seam 的高级用法。

现在准备开始吧!

项目安装

开发工具:

要想成功实践文中的范例就要下载最新版本的 Maven(我用的是 2.0.9 版本)。
安装 Maven 2.0.9+
设置 Maven 二进制版本的环境变量

例子中用到的服务器和二进制版本:

JBoss Portal’s Portlet Container 2.0
JBoss Portlet Bridge Beta3

目前,JBoss Portlet Bridge 是 JSR 301 规范的唯一实现,它允许你运行 JSF、RichFaces 和 Seam 的任意组合。你项目的 Maven 配置可安排下载打包在一起的 JBoss AS 和 JBoss Portlet Container 2.0,如果你想分别下载它们,可以在此处找到这些文件。否则,就给Maven 几分钟让它去自行下载适当的文件。

注意——在当前的2.6.5.SP1 版本的JBoss Portal 中同样可以运行这个portlet ,我在本文中使用了JBoss Portlet Container 2.0,但是桥(bridge)在两者中都能工作。你可通过此处了解令其可在任意版本的JBoss Portal 中运行的配置方法。

下述 Maven 原型(Maven archetype)是创建项目的一种简易方式,可以快速建立并运行一个启始项目(或者模板项目)。一旦你运行了这些命令,就可获得实践本文示例所需的一切文件。

打开一个终端窗口并运行如下指令:

复制代码
mvn archetype:generate -DarchetypeGroupId=org.jboss.portletbridge.archetypes
-DarchetypeArtifactId=1.2-basic
-DarchetypeVersion=1.0.0.B3 -DgroupId=org.whatever.project -DartifactId=myprojectname
-DarchetypeRepository=http://repository.jboss.org/maven2/ -Dversion=1.0.0.B3

现在,找到你的新建项目所在文件目录(如果你使用的跟上面的例子一样,那么目录名就应该是 “myprojectname”),浏览其中刚刚创建的所有文件,你将会看到一个基本 Maven 文件结构,其中带有适用于本文范例的源码。现在你就可以打开最喜欢的 IDE 环境,引入这个 Maven 项目了。

Portlet 桥配置要求

从现在开始的开发过程更像是在 Servlet 世界中开发 JSF 应用,不同之处在于:处理类似单点登录这样的问题;诸如命名空间(namespacing)这样的需要 portletContext 和访问变量的问题;以及 portlet 中像“Help”和“Edit”这样的窗口模式问题。我不想在本文讲述过多 portlet 的细节,但我会提供进行基本开发的必要信息。如果你想了解更多 portlets 的信息,请参考 JSR 168 JSR 286 规范说明。

JBoss Portlet Bridge 比较酷的一点在于它不是一个 portlet,它只是 portlet 和 JSF 之间的媒介。而你的 JSF 应用则是个 portlet,不过除了 WEB-INF 目录下 3 到 4 个额外的 xml 文件和关于 bridge 的 Jar 包外,它的其余部分与你的 Servlet 版本的应用毫无二致。下面几个配置文件是主要区别:

portlet.xml

复制代码
<portlet>
...v <portlet-class>
javax.portlet.faces.GenericFacesPortlet
</portlet-class>
<init-param>
<name>javax.portlet.faces.defaultViewId.view</name>
<value>/home.xhtml</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.edit</name>
<value>/jsf/edit.xhtml</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.help</name>
<value>/jsf/help.xhtml</value>
</init-param>
...
</portlet>

web.xml

复制代码
<context-param>
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
<param-value>
org.jboss.portletbridge.application.FaceletPortletViewHandler
</param-value>
</context-param>
<context-param>
<param-name>javax.portlet.faces.renderPolicy</param-name>
<param-value>
ALWAYS_DELEGATE
</param-value>
</context-param>

faces-config.xml

复制代码
<application>
<view-handler>
org.jboss.portletbridge.application.PortletViewHandler
</view-handler>
<state-manager>org.jboss.portletbridge.application.PortletStateManager</state-manager>
</application> <application></application>

由于上述设置已经应用在你刚刚设定的 Maven 原型中,因此现在我们就可以编译项目,并在 JBoss Portal 上部署它了。

运行 demo 程序

编译新项目,并通过如下两个步骤完成部署:

步骤 1:mvn install cargo:start -Premote-portal -Dpc20

这行命令将会花上几分钟去下载打在一起的 server+portal 包,所以在进行下一步骤之前,请耐心等待直至看到如下内容:

* 注意——在 server 启动前你还会看到一个 PortletException ,这很正常,而且它也是 Portlet Container 2.0 示例 FailDuringInitPortlet 的一部分。

接下来打开另外一个终端窗口,找到 JSF portlet 项目的根目录,并运行:

步骤 2:mvn cargo:deploy -Premote-portal -Dpc20

命令行参数通知 cargo 你正在运行的 portal 版本和 JBoss+Portal 包所在位置。这个例子同样可以运行于遵从 JSR 168 的最新版本 JBoss Portal 2.6.5.SP1 中。如果想了解更多 Maven 命令及相关信息,你可以参考 JBoss Portlet Bridge 文档。要查看已部署的 JSF portlet 情况可访问如下链接: http://localhost:8080/simple-portal/demo/jsr-301.jsp

JSF Portlet 开发

现在让我们来了解将 portlet 和 JSF 联系在一起的技术。

把你的 portlet 视作一个普通的 Web 应用

当把你的应用视作 servlet 端的 Web 应用时,portlet 桥是透明的。作为 portlet 开发人员,一种很好的做法是偶尔仔细检查一下你的应用以确保正在进行的开发没有扩大的趋势,因为它将运行在一个 portal 环境中。要查看此 demo 应用,或者任何已部署的带有桥的应用,可以访问 http://localhost:8080/JSFRIPortlet/home.jsf

命名空间

在 portal 环境中桥可以处理 JSF 的命名空间组合。当你需要在 JSF/xhtml 标记中使用元素 id 时,正常情况下在显示的标记中你所看到的是类似‘form1:myBtn’的代码,而如今在桥命名空间中你所看到的将是象:
jbpns_2fdefault_2fNews_2fStories_2fStoryTemplateWindow12snpbj:_viewRoot:form1:myBtn 这样的标记。

要克服这一点,你可以在你的 Facelets 页中应用下面的表达式,来为你的 javascript 代码预先设定命名空间:
document.getElementById('#{facesContext.externalContext.response.namespace}the_rest_of_JSF_ID');

请注意,因为使用了 portletResponse,所以一旦你试图在 servlet 应用端查看这个页面的时候就会得到一个异常。为避免这种情况的发生,你需要在你的后台 Bean(backing bean)中检查响应的类型,并为 UI 分配一个新的、“安全的”命名空间变量。

preserveActionParams

当你的 web.xml 文件中 preserveActionParams 值被设置为 TRUE 时,桥必须负责维护在 portlet 动作请求期间指派的任意参数,它们被保存在“桥请求域(bridge request scope)”中。当这个属性没有出现或者值为 FALSE 时,只在 portlet 请求作用域维护动作的请求参数。

复制代码
<init-param>
<param-name>javax.portlet.faces.preserveActionParams</param-name>
<param-value>true</param-value>
<init-param>

在你的 Facelets 页面中应用类似 #{request.yourParam}这样的代码可以利用这一设置。

排除桥请求域中的属性

当你的应用在每一次请求上都要使用请求属性而你又不想在扩展的桥请求作用域中管理特殊的属性时,你就必须在你的 faces-config.xml 文件中使用如下的配置了。下面你会看到任何命名空间为 foo.bar 的属性或者是以 foo.baz(通配符)打头的属性都会被从桥请求作用域中排除,这些属性只能用在每一次请求当中:

复制代码
<application>
<application-extension>
<bridge:excluded-attributes>
<bridge:excluded-attribute>foo.bar</bridge:excluded-attribute>
<bridge:excluded-attribute>foo.baz.*</bridge:excluded-attribute>
</bridge:excluded-attributes>
</application-extension>
</application>

或者你可以使用javax.portlet.faces.annotation.ExcludeFromManagedRequestScopej 注解,对你不想包含在请求中的对象类进行注解,也可以达到同样的效果。

结束语

正如你所看到的,JSR 301 规范不仅使得把已存在的 JSF web 应用建立成 portlet 更加容易,而且还提供给开发人员一种管理和处理 JSF 和 portlets 差异的方式。不过,规范目前仍处于频繁地评审和修订阶段。写这篇文章时最新的公开版本是 Early Draft Review 3,但是在 JSR 301 专家组内部,对此修订版本又已经有很多改进了,对桥比较重大的改进是在下一个 JBoss Portlet Bridge 版本(Beta 4)中将会实现的 portlet 模式导航和状态。

如果想了解更多项目信息和桥支持的兼容版本,或者想要参与社区论坛,请访问我们的项目页面 blog

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


志愿参与 InfoQ 中文站内容建设,请邮件至 editors@cn.infoq.com 。也欢迎大家到 InfoQ 中文站用户讨论组参与我们的线上讨论。

2008-11-13 00:482863
用户头像

发布了 127 篇内容, 共 47.0 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

软件测试 | Appium架构介绍与环境配置

测吧(北京)科技有限公司

测试

实现“无感知”的网络运维,新华社融媒体流量分析平台的创新之路

智维数据

大数据 防火墙 数据可视化 智能运维 运维安全

软件测试 | 控制特殊Toast识别

测吧(北京)科技有限公司

测试

谈JVM参数GC线程数ParallelGCThreads合理性设置

京东科技开发者

线程 JVM cpu GC线程 ParallelGCThreads

中国人寿业务稳定性保障:“1+1+N” 落地生产全链路压测

TakinTalks稳定性社区

一卡通|多云流量监控支撑To C+To B,双向高效运维

智维数据

大数据 数据可视化 智能运维 运维安全

可靠、安全、稳定,开源高质量项目 | 亚马逊的开源文化

亚马逊云科技 (Amazon Web Services)

ChatGPT 最好的替代品

图灵教育

机器学习 BERT ChatGPT

软件测试 | 显示等待机制

测吧(北京)科技有限公司

测试

ChatGPT搜索风暴

OneFlow

人工智能 深度学习

软件测试 | 触屏操作测试自动化

测吧(北京)科技有限公司

测试

软件测试 | 录制Appium测试用例

测吧(北京)科技有限公司

测试

软件测试 | 高级定位技巧

测吧(北京)科技有限公司

测试

软件测试 | App控件交互

测吧(北京)科技有限公司

测试

机器学习洞察 | 一文带你“讲透” JAX

亚马逊云科技 (Amazon Web Services)

ChatGPT 最好的替代品

图灵社区

机器学习 Transformer BERT ChatGPT

应用交付可视化助力金融科技企业应用服务质量及效率提升

智维数据

数据可视化 智能运维 应用交付 流量分析系统

3dmax的常用功能和使用方法

Finovy Cloud

3D渲染 3DMAX

4道数学题,求解极狐GitLab CI 流水线|第2&3题:父子流水线 + 多项目流水线

极狐GitLab

ci DevOps pipeline 极狐GitLab 流水线

行业分析| 智能无人自助设备

anyRTC开发者

人工智能 音视频 智能无人自助设备 自动售货机 无人超市

软件测试 | adb命令的组成

测吧(北京)科技有限公司

测试

怎么编写接口测试用例?

Liam

测试用例 如何编写测试 测试用例设计

软件测试 | 元素定位方式与隐式等待

测吧(北京)科技有限公司

测试

软件测试 | App控件定位

测吧(北京)科技有限公司

测试

应用交付可视化助力互联网行业提升办公网效率与满意度

智维数据

数据可视化 智能运维 应用交付 运维安全 流量分析系统

拜占庭将军问题和 Raft 共识算法讲解

京东科技开发者

算法 分布式系统 拜占庭将军问题 raft共识算法 日志同步

理论+实践,揭秘昇腾CANN算子开发

华为云开发者联盟

人工智能 AI 华为云 企业号 2 月 PK 榜 华为云开发者联盟

软件测试 | App常见Bug解析

测吧(北京)科技有限公司

测试

袋鼠云产品功能更新报告04期丨2023年首次,产品升级“狂飙”

袋鼠云数栈

Slurm集群调度策略详解(2)-回填调度

慕冰

Slurm 回填调度

设计模式第七讲-外观模式、适配器模式、模板方法模式详解

C++后台开发

设计模式 后端开发 Linux服务器开发 适配器模式 C++开发

应用JSF、Ajax和Seam开发Portlets(1/3)_Java_Wesley Hales_InfoQ精选文章