2025上半年,最新 AI实践都在这!20+ 应用案例,任听一场议题就值回票价 了解详情
写点什么

应用 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:482814
用户头像

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

关注

评论

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

面试官上来就让手撕HashMap的7种遍历方式,当场愣住,最后只写出了3种

不在线第一只蜗牛

Python 程序员 面试 开发语言

微店商品详情 API 的调用频率有限制吗?

技术冰糖葫芦

API 文档

数据与特征:解密模型解决实际问题的关键

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

测试

TikTok直播:是否需要专线,以及加速的方法有哪些?

Ogcloud

海外直播专线 Tik Tok直播 Tik Tok直播网络 直播加速 海外直播

如何选择合适的数据提升模型性能

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

测试

item_get-根据ID取商品详情(shopee.item_get):提高跨境电商交易效率的关键

技术冰糖葫芦

API 文档

数据闭环构建技巧:确保模型稳定性与数据质量

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

测试

云游戏:畅享3A游戏大作的全新时代

Ogcloud

游戏 云游戏 3A游戏 3A云游戏

人工智能发展史:从专家系统到机器学习的演进

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

测试

评估模型效果:深入解读混淆矩阵、精准率、召回率和F1 score

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

测试

数据挑选技巧:提升模型质量的关键一步

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

测试

自学习概念探析:构建稳定模型的核心思想

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

测试

自学习的现实应用:构建智能系统的新思路

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

测试

DevChat上新:/commit让你躺平都能写好规范的提交消息

思码逸研发效能

训练集、验证集和测试集:区别与应用详解

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

测试

坐标 DISTRIBUTECH,TDengine 发力海外电力行业

TDengine

tdengine 时序数据库

智达方通总经理蔡志宏先生受邀参与哈工大京津冀校友发展研讨会,共话科技创新与发展新篇章

智达方通

智达方通 企业绩效管理 预算管理 哈工大 校友会

基于图数据库构建知识图谱平台应用实践

星环科技

Spark在分布式造数工具中的应用探索

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

测试

从历史视角看人工智能:专家系统、机器学习与深度学习

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

测试

深入理解训练集、验证集和测试集在模型训练中的作用

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

测试

Pygame:实现Python游戏开发的跨平台梦想

技术冰糖葫芦

API 文档

实时数据驱动:API商品数据接口引领业务飞跃

Noah

JavaScript 的 structuredClone:深拷贝技术全解析

Liam

JavaScript 前端 Web 前端开发 structuredClone

Spark技巧大揭秘:构建分布式造数工具加速工作效率

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

测试

新一代湖仓集存储,多模型统一架构,高效挖掘数据价值

星环科技

数据闭环的建立:确保模型发展的可持续性

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

测试

产品更新 | 思码逸 DevInsight,新增虚拟项目团队的管理与度量

思码逸研发效能

思码逸获得 InfoQ 2023 年度技术生态构建奖

思码逸研发效能

TikTok直播专线,全程稳定的专属网络

Ogcloud

Tik Tok直播 Tik Tok直播网络 Tik Tok 海外直播 直播专线

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