写点什么

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

  • 2008-12-19
  • 本文字数:5242 字

    阅读完需:约 17 分钟

在这个系列文章的第一篇第二篇中,我解释了什么是portlet bridge?以及如何在一个基本的JSF 和基于RichFaces(Ajax)的portlet 中安装和使用它,和当前能支持运行JBoss Portlet Bridge 的portal 服务器的主要区别。最后这篇文章将集中讲述Seam portlet 的开发,和最新发布的 JBoss Portlet Bridge Beta 4 版本的所有特性和优势。对于不太熟悉 portlets 的读者来说,仔细阅读前面两篇文章会有助于更好的理解本文。

现在让我们先从 Seam portlet 的开发入手。

安装 Seam Portlet

开发工具:

要仿照本文示例进行开发,就需要下载最新版本的 Maven(我用的是 2.0.9 版本)。
安装 Maven 2.0.9+
在机器上设置Maven binaries 的path 环境变量

创建项目:

不同的 Maven 原型(archetype)对应可以产生不同种类的 bridge。直接从命令行运行如下代码,可创建你的 Seam portlet 项目:

复制代码
mvn archetype:generate
-DarchetypeGroupId=org.jboss.portletbridge.archetypes
-DarchetypeArtifactId=seam-basic -DarchetypeVersion=1.0.0.B4
-DgroupId=org.my.project -DartifactId=seamproject
-DarchetypeRepository=http://repository.jboss.org/maven2/ -Dversion=1.0.0.B4

该特定原型是模块化的,这意味着通过其产生的项目将由几个子项目构成。这样做的好处是源码、资源和配置之间的界限更加清晰,维护也更方便。上述命令将产生三个目录,其中,‘web’目录中包含标记文件、图片和 WEB-INF xml 配置文件;‘ejb’目录中包含所有 Seam EJB3 源码,以及任何跟持久化和 ejb 部署相关的 xml 配置文件信息;最后是‘ear’目录,它主要用来集合项目信息构建 ear 文件。

如果你是用上面提到的原型(archetype)命令创建的项目,那么现在你就会有一个‘seamproject’目录。现在到该目录下并运行如下命令:

mvn install 这个命令将会帮助你下载本地 Maven 库中缺少的任何组件,并编译和构建 ear 文件。

运行和部署 portlet:

既然你已经有一个可部署的 ear 文件,那么再利用下面的命令就可以轻松的将 portlet 部署到最新版本的 JBoss Portal 上(已绑定到 JBoss 应用服务器)了。如果你已经自己下载或创建了本地安装包,就可在 bridge 文档中找到使用自定义配置的说明了。

现在转到{seamproject}/ear 目录下运行如下命令:

复制代码
mvn cargo:start -Premote-portal-Dportal-2.7.0.B1

该命令将花上一段时间(视你的网络情况而定)来下载最新版本的 JBoss Application Server 和 JBoss Portal(软件均位于 SourceForge.net 网站上)。在继续下一步骤之前你应该能看到与上文画面相似的日志记录。* 注意:你也许还会看到日志记录中不断滚屏的 WSRP 信息,不用担心,这同样是证明你已准备就绪的标志。

现在来部署你的 Seam 项目 ear 文件。新打开一个终端窗口,转到目录{seamproject}/ear 下,运行如下命令:

复制代码
mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

当你在服务器日志中看到 ear 文件已部署成功时,访问链接 http://localhost:8080/portal/portal/default/seamproject ,会看到如下页面:

现在我们已经准备好一个要开发 Seam portlet 了。当然,应用程序到底怎么写是由开发人员来决定的事情。但是这会帮你摆脱那些琐碎的配置问题,轻松的开始工作。

配置

将 JSF portlet 转换为一个典型的 Seam 应用,只需要少量的配置工作即可完成。下面的配置文件代码省略了前面文章(第一部分第二部分)已经提到过的配置信息。如果想了解详细内容,请参照bridge 文档的配置部分

web.xml
------------------

下面的这段配置通常是任何 Seam 应用中都会有的内容,并且不会因为 portlet 环境而有所不同:

复制代码
<listener>
<listener-class>
org.jboss.seam.servlet.SeamListener
</listener-class>
</listener>
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>
org.jboss.seam.servlet.SeamResourceServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Seam Filter</filter-name>
<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dspatcher>
</filter-mapping>

配置 ExceptionHandler 上下文参数,可允许 bridge 应用现成的异常处理器去解决基于 Seam 的异常。如果愿意的话,你也完全可以应用自己的实现:

复制代码
<context-param>
<param-name>org.jboss.portletbridge.ExceptionHandler</param-name>
<param-value>
org.jboss.portletbridge.SeamExceptionHandlerImpl
</param-value>
</context-param>

Bridgelet 是针对 portlet bridge 扩展(extension)的名称。portlet bridge 社区一直在积极的开发一些扩展以增强或集中 JBoss Portal、Seam 和 Richfaces 三者的特性,例如,PortalIdentity(SSO)seam 组件可允许你把 jar 文件放在你的 classpath 上,这样你立刻就会有一个可用于 Seam 和 Portal 之间的 SSO 了。你也可以在 Maven pom 中将这个扩展配置成一个依赖(象下面将看到的那样)。

如果你对 Bridgelet 有什么建议,或者有意参与 JBoss Portlet Bridge 的开发工作,那么我们期待你积极加入我们的论坛并提交 Jira tasks

Seam 应用和 JBoss Portal 之间的单点登录问题

开发人员可以把 Seam Booking Demo 用做一个开发和测试的 portlet 参考程序。如果想了解和实践 SSO Bridgelet,你可以从此地址 http://anonsvn.jboss.org/repos/portletbridge/tags/1.0.0.B4/examples/seam/booking/ 下载源代码,然后运行与此篇文章上面刚刚讲过的完全相同的 maven 部署命令(或者是下面将要讲到的简短版本)来部署和运行该程序。

简短版本是:
转到{SeamBooking}根目录下,运行如下命令:
mvn install

然后再转到{SeamBooking}/ear 目录下,运行:
mvn cargo:start -Premote-portal-Dportal-2.7.0.B1

现在再来部署你的 Seam 项目 ear 文件。新打开一个终端窗口,在{SeamBooking}/ear 目录下运行如下命令:
mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

一旦你部署完成并运行 demo 后,就可以访问链接 http://localhost:8080/portal/portal/default/SeamBooking 继续下面的步骤了。点击“注册新用户(Register New User)",新建一个用户并用其登录系统:

登录之后你将会看到酒店搜索页面,还有与当前登录角色对应的所有功能。但是,如果你看向屏幕右上角,你会发现登录到 Seam 应用和你的 JBoss Portal 用户 / 管理员账户一点关系都没有:

这就是我们需要 SSO Bridgelet 的理由,它允许通过 Seam 身份认证模块来验证 JBoss Portal 用户名。现在让我们来尝试一下:
令服务器依然保持运行状态,在进行部署的那个终端窗口中,返回到上一级目录,也就是{SeamBooking}/ 根目录下运行如下命令:
mvn install -Psso

接下来再转到{SeamBooking}/ear 目录下运行如下命令:
mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

通过上述命令我们将 SSO jar 包嵌入进了应用,并重新部署了一次 ear 文件。

现在,让我们回到 http://localhost:8080/portal/portal/default/SeamBooking 上的 portlet。这次我们登录到 portal 而不是 Seam 应用。点击页面右上方的 portal login 进行登录,用户名和密码都是‘admin’。

如果这是一个现实中的应用,我们会对 UI 做一点调整,把 Seam 应用的登录表单隐藏起来。同时因为 SSO 的存在,我们可以调整网站其它基于角色的内容。但是,正如我前面所说,这是从最原始状态的 Seam booking demo 出发做最小改动能达到的效果,只是一个参考。

登录到 JBoss Portal 后,在你的 Seam 和 Portal UI 上你将会看到如下内容:

在解决了 Portal 和你的 Seam 应用之间的身份认证问题后,应用的创建就变得容易些了。如果你的 Seam portlet 是基于 Maven 创建的,那么还需要你做的就只有在 pom.xml 文件中添加如下代码了:

复制代码
<dependency>
<groupId>org.jboss.portletbridge.extensions.seam</groupId>
<artifactId>PortalIdentity</artifactId>
<version>1.0.0.B4</version>
</dependency>

或者你也可以把 PoralIdentity.jar 文件放到应用程序 WEB-INF/lib 目录下就行了,不再需要做别的配置了。

JBoss Portlet Bridge Beta4 概述

既然这是本系列文章的最后一篇,那么在最后一部分我将介绍 9 月 11 日刚刚发布的 JBoss Portlet Bridge Beta 4 版本的新特性。

支持 PortletMode 变化

一个 PortletMode 代表了应用中一个不同的展现路径(render path),有三种标准的模式:view、edit 和 help。bridge 的 ExternalContext.encodeActionURL 可以辨认查询字符串参数 javax.portlet.faces.PortletMode,并用这个参数值在底层 portlet actionURL 或响应上设置 portlet 模式。 一旦处理完就要把这个参数从查询字符串中去掉。下述导航规则将会在 portlet 的 edit 模式下呈现 viewId 为\edit.jspx 的页面:

复制代码
<navigation-rule>
<from-view-id>/register.jspx</from-view-id>
<navigation-case>
<from-outcome>edit</from-outcome>
<to-view-id>/edit.jspx?javax.portlet.faces.PortletMode=edit</to-view-id>
</navigation-case>
</navigation-rule>

导航至一个模式的最终 viewId

缺省地,一个模式的改变将从模式的默认视图(不带状态)开始。对于一个普通的 portlet 模式,在其返回到进入另一模式之前的那个模式时(例如:view->edit->view),它将会跳转到这个模式(离开之前)的最终视图(和状态)。bridge 能够对必要信息进行清楚的编码,以便有需要返回到前一个模式时,它可以定位到适当的视图,并恢复到应有的状态。开发人员可以使用由 bridge 维护的 session 属性,以便从一个模式导航回其前一个模式的最终位置和状态。同样,开发人员需要描述一个动态导航:“从视图 X 返回到模式 Y 的最终视图”。这可以用由 EL 表达式简单地表示如下:

复制代码
<navigation-rule>
<from-view-id>/edit.jspx*</from-view-id>
<navigation-case>
<from-outcome>view</from-outcome>
<to-view-id>#{sessionScope['javax.portlet.faces.viewIdHistory.view']}</to-view-id>
</navigation-case>
</navigation-rule>

Portlet 开发人员需要注意的问题

根据 bridge 实现,当用到这些 session 范围的属性值、或者任何可能包含查询字符串参数的 viewIds 时,最好在验证规则目标(rule target)时使用通配符语法。例如,上面的<to-view-id>表达式返回的是一个表单的 viewId(/viewId?javax.portlet.faces.PortletMode=view&....)。其不含通配符,因此当该新视图发生页面跳转时,导航规则就无法解析了,因为它找不到任何可与之完全匹配的对象。

而上面的edit.jspx <from-view-id>包含了通配符,导航规则就可用查询串(<to-view-id> /edit.jspx?javax.portlet.faces.PortletMode=edit </to-view-id>)来和它匹配。强烈建议开发人员都使用这种通配符以确保程序可以在各种 bridge 实现中正常执行。

处理 Portlet 中的 Ajax 错误

默认的,错误是由处理 Ajax 请求的标准 servlet 页面来解决。要在 portlet 内部处理错误,就要用到下面的 JavaScript 代码:

复制代码
<script type="text/javascript">
A4J.AJAX.onError = function(req,status,message){
window.alert("Custom onError handler "+message);
}
A4J.AJAX.onExpired = function(loc,expiredMsg){
if(window.confirm("Custom onExpired handler "+expiredMsg+" for a location: "+loc)){
return loc;
} else {
return false;
}
}
</script>

结论

正如前面所说,portlet bridge 社区从项目早期测试阶段就已经开始发布补丁和其它形式的帮助来促进其发展。虽然项目的核心是 JSR-301 规范,然而整合 Seam、 Richfaces、Portal 和 Bridgelets 以及其它辅助性的加强功能是具有无限潜能和意义的。已经有些开发人员为项目的发展贡献了他们的力量,在此我们对所有这些提供过补丁、增强构件以及在论坛上积极回答问题的人们表示衷心的感谢。

最后,这是一个基于社区的项目,提供帮助和反馈的开发人员越多,我们的新产品发布的越快,其功能也就更强,代码也更完善。预计 GA 版本会在 09 年初发布。

论坛上提供反馈非常有用,我们也很欢迎。如果你想要了解更多关于JBoss Portlet Bridge 项目的信息可以访问我们的项目和文档页面

相关阅读

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


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

2008-12-19 00:301737
用户头像

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

关注

评论

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

2022 IoTDB Summit:Apache IoTDB PMC 张金瑞《为物联网场景优化的时序数据库共识协议》

Apache IoTDB

大数据 IoTDB

会声会影2023中文最新版消息

茶色酒

会声会影2023

Clean Start与Session Expiry Interval - MQTT 5.0新特性

EMQ映云科技

物联网 IoT mqtt 客户端 企业号 3 月 PK 榜

ChatGPT Turbo API 18元/100万个单词

kcodez

openai ChatGPT

JDK 环境配置

流火

Java centos jdk window

在文心一言出生地,百度悄悄燃烧AI小宇宙

白洞计划

百度 文心一言

在深圳龙岗,看见空间智能化的潮水涌动

脑极体

全屋智能

Portraiture4中文免费ps滤镜磨皮插件

茶色酒

Portraiture3

图像的滤波与图像增强的Matlab实现

timerring

数字图像处理

SpringBoot+ThreadPoolTaskExecutor 批量插入百万级数据实测

做梦都在改BUG

Java Spring Boot 多线程 ThreadPoolTaskExecutor

老铁们看过来!2023首场昇腾AI开发者创享日来到“东北黑土地”沈阳

科技热闻

得物供应链复杂业务实时数仓建设之路

小小怪下士

Java 程序员 后端

赞不绝口!仅靠阿里P9分享的 Redis 工作手册,拿到60W年薪Offer

做梦都在改BUG

Java 数据库 redis 缓存 面试

LeetCode题解:2373. 矩阵中的局部最大值,遍历,详细注释

Lee Chen

JavaScript LeetCode

MongoDB写入数据策略

NineData

nosql mongodb Journaling 写入策略 读策略

【我在京东做研发】揭秘支撑京东万人规模技术人员协作的行云DevOps平台

京东科技开发者

FL Studio2023免费中文版数字音频工作站软件

茶色酒

FL Studio2023

人工智能+低代码,打通AI落地的最后“一公里”

明道云

字字珠玑!GitHub爆赞的网络协议手册,被华为大佬指定内部必学?

做梦都在改BUG

Java 计算机网络 网络协议

堪称神级!GitHub上标星157K的Java教程,全程干货,只讲重点

做梦都在改BUG

Java

软件测试 | YAML是什么?

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

测试

Hypium框架使能ArkTS应用高效测试

HarmonyOS开发者

HarmonyOS

2022 IoTDB Summit:IoTDB PMC 曹高飞《Apache IoTDB 秒级扩容能力与存算分离实践》

Apache IoTDB

数据库 IoTDB

开源如何推动云计算的发展与创新 | 雨林开源行

开源雨林

开源 kubenetes OpenStack

架构实战营模块1第3课 - 什么是面向复杂度架构设计

净意

新必应(New Bing)申请出错终极方案

kcodez

微软 ChatGPT New Bing

2022 IoTDB Summit:IoTDB PMC 田原《大规模并行处理与边缘计算在 Apache IoTDB 中的实践》

Apache IoTDB

数据库 IoTDB

ClickHouse 与 Amazon S3 结合?一起来探索其中奥秘

亚马逊云科技 (Amazon Web Services)

再有人问你什么是分库分表,直接把这篇文章发给他

做梦都在改BUG

Java 分库分表

高性能存储SIG月度动态:ANCK 5.10正式支持ublk、erofs容器镜像按需读时延优化60%

OpenAnolis小助手

操作系统 高性能存储 龙蜥社区 sig

零基础如何学习Web 安全,如何让普通人快速入门网络安全?

网络安全学海

黑客 网络安全 信息安全 渗透测试 WEB安全

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