写点什么

使用 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:302011
用户头像

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

关注

评论

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

《精通Tomcat:Java Web应用开发、框架分析与案例实战》.pdf

田维常

tomcat

IMC总决赛精彩对战应接不暇,英特尔酷睿极致性能燃爆比赛现场!

E科讯

数据结构与算法系列之递归(GO)

书旅

数据结构与算法 Go 语言

LeetCode题解:剑指 Offer 22. 链表中倒数第k个节点,双指针,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

亲测三遍!8步搭建一个属于自己的网站

华为云开发者联盟

MySQL Linux 开发者 网站 华为云

Teambition 网盘 VS 阿里云盘:阿里这个浓眉大眼的也开始玩赛马了?

郭旭东

阿里云 阿里云网盘

Github标星67.9k的微服务架构以及架构设计模式笔记我真的爱了

Java架构之路

Java 程序员 架构 面试 编程语言

“双11”购物狂欢节,所有女生走进了谁的直播间?

博睿数据

APM AIOPS 拨测 直播 用户体验

数字投票时代即将到来

CECBC

数字投票

java-File对象

Isuodut

握草!美团P8整理的280页超详细Docker实战文档简直太香了,让你对如日中天的Docker有更深入的了解。

Java架构之路

Java 程序员 架构 面试 编程语言

云图说|多模态AI开发套件HiLens Kit:超强算力彰显云上实力

华为云开发者联盟

人工智能 开发者 物联网 机器人 华为云

C++多元组tuple使用方法?你熟悉吗?快来看看吧

良知犹存

c++

【Swift实现代码】iOS架构模式之MVP

码爷

ios swift 架构

Flutter Bloc模式

码爷

flutter ios 程序员

《迅雷链精品课》第三课:区块链主流框架分析

迅雷链

区块链 区块链方案 区块链+ 区块链应用

高交会科技盛宴:“科技改变生活,创新驱动发展”

13530558032

手把手教你本地 k8s 集群搭建云原生 Tekton CICD 流水线

比伯

Java 大数据 编程 架构 计算机

DeFi质押挖矿系统开发技术

薇電13242772558

区块链 defi

美国区块链政策大盘点

CECBC

区块链 政策 货币

微众银行大数据平台建设方案

康月牙

大数据 开源 金融 平台 微众银行

【涂鸦物联网足迹】涂鸦云平台接口列表

IoT云工坊

人工智能 接口 物联网 API 智能家居

区块链有了几个新“标准”!

CECBC

区块链 版权保护

轻松云上揽胜中华,靠的就是这份聪明的“地图”!

华为云开发者联盟

MySQL 数据库 postgresql AI 地图

阿里大牛说:你凭什么搞不懂SpringBoot,Cloud,Nginx与Docker

小Q

Java 学习 编程 架构 面试

多线程并发主题-ThreadLocalRandom类

公众号:程序猿成神之路

Java 并发编程 线程

为什么我就面试阿里P6,好不容易过2面,3面来个架构师来吊打我?

小Q

Java 学习 程序员 架构 面试

HTTPDNS开源 Android SDK,赋能更多开发者参与共建

移动研发平台EMAS

android 阿里云 开源 httpdns 移动研发平台

JVM真香系列:方法区、堆、栈之间到底有什么关系

田维常

Java JVM 堆栈 方法区 Java虚拟机

加快脑动脉瘤检测,AI来了

华为云开发者联盟

人工智能 学习 算法 华为云 医疗AI

企业级软件的核心价值

Philips

敏捷开发 企业应用

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