InfoQ

InfoQ

文章

我的书签

登录注册 以永久保存书签。

该内容已经被标记书签!

标记书签错误,请重试!

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

作者 Wesley Hales 译者 张凯峰 发布于 2008年11月13日

领域
运维 & 基础架构,
语言 & 开发
主题
门户/内容管理系统 ,
Java
标签
JSF

如果你刚开始考虑应用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 168JSR 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> 

由于上述设置已经应用在你刚刚设定的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年sun科技日门票转让 发表人 wenhao zeng 发表于
  1. 返回顶部

    2008年sun科技日门票转让

    发表人 wenhao zeng

    由于本人临时要到外地出差,故低价转让!
    现价:100元
    原价:398元
    日期:2008年11月21—22日
    门票含两日午餐券、两日礼品换购券
    QQ:540049650
    手机:13811682379

深度内容

大规模视频网站的计费与流量管理

本次分享将会就大规模视频网站的计费与流量管理这个话题,从操作层面细细进行讲解和分析,为系统工程师们揭示平日里我们没有关心的另一些内容。同时也希望本次分享能揭示行业中的一些“潜规则”,让互联网行业的流量与带宽管理更为开放与简洁。
本次演讲视频录制于QCon杭州2011

专访Jeffrey Richter:Windows 8是微软的重中之重

Jeffrey Richter以其多本Windows核心技术的经典著作而闻名,同时,他深入掌握微软的.NET等一系列核心技术,2012年1月,Jeffrey Richter在北京接受了InfoQ中文站的专访,谈到Windows 8和WinRT编程,并就异步编程、Windows编程中的可扩展性、性能和安全性方面给出自己的建议。

应用云平台的可用性——从新浪SAE看云平台设计

云计算平台的可用性,相比传统互联网服务而言,更加复杂和困难,也更具有挑战性。本文借助新浪SAE云平台为读者讲述了云平台可用性的定义、如何打造高可用的平台,以及对云计算的用户提出了建议。

JVM定制改进 @ 淘宝

淘宝高度重视Java平台的健康发展,组建了一个团队专注于Java平台的底层部分的性能、功能与稳定性改进;工作主要基于OpenJDK中的HotSpot VM开展,其中一些通用的功能随后也会逐渐反馈给OpenJDK社区。希望能与使用Java平台开发应用的大家交流经验。
本次演讲视频录制于QCon杭州2011

"伤得起"的云计算应用——对云端应用之架构的思考

2011年4月21日至22日是值得云计算从业者纪念的日子。Amazon的IaaS服务出现故障,导致许多商业网站的服务中断,影响非常严重。作为云计算用户,我们需要思考的是,如何保证即便在云服务不可用的情况,我们的应用架构仍然能够屹立不倒?本文正是站在云计算用户的角度试图探讨这一问题。

让交付的速度跟上思考的速度

12人的技术团队,4组刀片服务器,每月20亿的访问量,每日1次准时部署,99.9%的可用性。这可能吗?当然。想知道如何做的吗?百姓网将与您分享他们在DevOps实践过程中的经验和技巧。
本次演讲视频录制于QCon杭州2011

架构之路——穿行在产品和业务之间

篱笆作为一家起源于社区的电子商务公司,反映到技术层面就是同时要面对产品和业务,以及经营战略的变化调整。如何在产品和业务的夹缝之间完成技术架构的抽象与平衡,寻找更有效的价值定位,这当中有些经验教训和个人感悟愿与众人分享。
本次演讲视频录制于QCon杭州2011

特性注入:成功三部曲

本文将对特性注入以及相关方法做一个扫盲性的介绍。我们会解释这个框架的关键要素,并附上实例来证实它们。为了让文章保持相对较短,我们不会深入到某个工具或方法中,而是会给出一些参考资料,以便大家做进一步的研究。