QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

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

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

关注

评论

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

Web 键盘输入法应用开发指南 (3) —— 输入法事件

天择

JavaScript 键盘 输入法 3月月更

从Nacos到完全自研|得物的注册中心演进之路

得物技术

架构 raft 注册中心 实例 兼容性测试

2022年1月娱乐直播行业用户洞察:行业格局稳定,内容运营精细化

易观分析

EMQ 正式成为 OASIS 最高级别成员,主导推进物联网协议标准化应用

EMQ映云科技

开源 物联网 ibm mqtt OASIS

如何获取 Docker 容器的 IP 地址

AlwaysBeta

Docker 容器

【C语言】一篇速通操作符

謓泽

C语言 操作符 3月月更

Camtasia Studio2022激活码序列号

茶色酒

Camtasia Studio2022

如何搭建FAQ文档?只需四步

小炮

企业管理工具

上手体验!如何借助龙蜥实验室快速部署 Web 应用?

OpenAnolis小助手

开源 国产操作系统 web服务器

Tuxera2022mac读写硬盘U盘工具

茶色酒

Tuxera2022

使用 Recast.AI 创建具有人工智能的聊天机器人

汪子熙

人工智能 机器学习 聊天机器人 CRM 3月月更

恒源云(GPUSHARE)_超越预训练 NLP 的模型来喽

恒源云

自然语言处理 深度学习 算法

混合云管平台排名您知道吗?看这里!

行云管家

混合云 云管

刚刚,我们收到了北京冬奥组委的感谢信

阿里巴巴云原生

阿里云 云原生 冬奥会 合作

企业培训赛道大火,谁能真正解企业人才培训之急?

ToB行业头条

一文全面掌握大数据关联与汇聚

云智慧AIOps社区

redis Clickhouse flink sql 大数据开发

Linux之route命令

入门小站

Linux

高性能图计算系统 Plato 在 Nebula Graph 中的实践

NebulaGraph

图数据库 图计算 分布式图数据库

web前端培训:Vue3 调度系统的深度剖析

@零度

Vue 前端开发

脱颖而出!OceanBase 入选 2021“科创中国”开源创新榜单

OceanBase 数据库

数据库 分布式 OceanBase 开源 科创中国

大数据培训:Spark高频面试题汇总

@零度

大数据 spark

微服务身份认证需求下的私钥托管痛点与破局

全象云低代码

微服务 低代码 身份认证 鉴权 密钥

《隐私计算》重磅发布,全面、系统论述数据要素安全流通价值

博文视点Broadview

2022年的SaaS行业,钱往哪里去?

ToB行业头条

在线HTML转JSX工具

入门小站

工具

DM 中 relay log 性能优化实践丨TiDB 工具分享

PingCAP

始于信任 忠于专业|DataPipeline收到一封来自山东城商行联盟的感谢信

DataPipeline数见科技

2022年数据库审计厂家就选行云管家!功能强大!

行云管家

数据库 网络安全 数据库审计

《重构 JavaScript》读后感和部分摘录

道道里

前端 测试 重构

小程序已成为超级APP必选项,逐鹿私域“留量”

Speedoooo

小程序 APP开发 软件开发、 轻量应用 小程序管理平台

会声会影2022脸部索引功能详解

懒得勤快

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