BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

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

| 作者 Wesley Hales 关注 0 他的粉丝 ,译者 张凯峰 关注 1 他的粉丝 发布于 2008年12月20日. 估计阅读时间: 22 分钟 | 如何结合区块链技术,帮助企业降本增效?让我们深度了解几个成功的案例。

在这个系列文章的第一篇第二篇中,我解释了什么是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中文站用户讨论组参与我们的线上讨论。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT