在Portal应用中,有时候不同的Portlet之间需要能够互相通信,即一个portlet的状态发生改变,要通知其他的portlet,这些收到通知的Portlet状态也要做相应的改变。在Weblogic Portal中,通过事件的发布订阅机制来实现portlet之间的通信,使Portlet之间可以进行一对一、一对多、多对多等不同的通信模式,以满足不同应用场景的需要。下面具体介绍。
采用Event Handle事件监听触发机制
通过事件的发布订阅机制来实现portlet之间的通信,Portlet状态改变会触发不同的事件,也可以定制自己的事件。如下图,通过简单的配置就可以工作。

具体原理和配置方法, 可参考wlp814文档 http://e-docs.bea.com/wlp/docs81/ipcguide/index.html
该文档有两个例子,通过Backing File方式进行。 Event Handle机制对不在同一Page上的Portlet也可以生效。这种通信方式在SP4版本开始才有。
采用Listen to Instance lable方式
通过配置Portlet的Listen to属性为另一个Portlet的Instance lable,就可以实现Portlet之间的参数传递。其具体原理和配置方法,可参考wlp813文档: http://e-docs.bea.com/wlp/docs81/sp3/pdf/ipcguide.pdf
该文档说明了4个例子,采用4种不同的通信方式。代码可以从https://codesamples.projects.dev2dev.bea.com/servlets/Scarab?id=S67下载。
Pageflow Portlet to Pageflow Portlet
Pageflow Portlet to Non-Pageflow Portlet
Non-Pageflow Portlet to Non-Pageflow Portlet
Non-Pageflow Portlet to Pageflow Portlet
采用Listen To方式,一个Portlet可以同时听多个其他Portlet, 在设置Listen to属性时,通过空格分开。采用Listen To方式,对不在同一Page上的Portlet也可以生效。
(注意:listenTo 特性与其他 Portlet 的 instanceLabel 关联。可以更改 definitionLabel,而不会影响 listenTo 行为。Instance Label属性在.portal文件上选中该Portlet,然后在属性栏中设置。如下图:)

在设置了Listen To属性的Portlet 的 .jpf 文件中,必须执行两项操作之一采用正常工作。否则会报Exception:action not found
方法1:使用与第一个页面流中相同的操作方法签名。例如,此操作定义来自 Portlet 2 的页面流控制器:
/**
* @jpf:action
* @jpf:forward name="listening" path="listening.jsp"
*/
public Forward passString1(portlets.j1.j1Controller.Form form)
{
thePassedText = form.getText();
return new Forward( "listening" );
}
方法2:可以为 ActionNotFoundException添加处理程序。例如,在 Portlet 2 的页面流控制器中,确保以类级别定义 @jpf:catch 批注:(在PAGEFLOW的最前面)。
/**
* @jpf:controller
* @jpf:catch type="ActionNotFoundException" method="doNothing"
* @jpf:view-properties view-properties::
*
*
并且在相同的页面流控制器中,确保定义了某种操作方法,如下所示:
/**
* @jpf:exception-handler
* @jpf:forward name="current" return-to="currentPage"
*/
protected Forward doNothing( ActionNotFoundException e, String actionName, String message, FormData form )
{
return new Forward( "current" );
}
把Return 拖入pageflow:

对基于jsp的portlet可以采用传递参数的简单办法
对放在同一个页面(PAGE或BOOK)上的Portlet.如果其中的某个Portlet做了提交等操作或点IE上的刷新按钮导致portal刷新, portal都会从头到尾render每一个portlet(设置缓存的除外)。这样你在一个portlet设置的参数可以在另外的portlet中通过request.getparamete()获取。所以要注意同一个页面上的portlet中的request参数名称不要一样,Page Flow中的Action名称也要不一样。具体可采用:
具体请参考wlp813文档http://e-docs.bea.com/wlp/docs81/sp3/pdf/ipcguide.pdf。
参考例子下载地址:https://codesamples.projects.dev2dev.bea.com/servlets/Scarab?id=S67
采用Request对象传递参数方式
这种方式只适用于Page Flow Portlet和非Page Flow Portlet之间的通讯。并且Portlet必须在同一个Page或Book上。在Page Flow Portlet中通过ScopedServletUtils获取到外部的Request对象,然后把要传递的参数通过setAttribute传入,如下例子所示:
HttpServletRequest scopedRequest = getRequest();
HttpServletRequest outerRequest = ScopedServletUtils.getOuterRequest(scopedRequest);
outerRequest.setAttribute("selectedItem", scopedRequest.getParameter("selectedItem"));
具体请参考wlp813文档: http://e-docs.bea.com/wlp/docs81/sp3/pdf/ipcguide.pdf
参考例子下载地址:https://codesamples.projects.dev2dev.bea.com/servlets/Scarab?id=S67
作者简介
dev2dev ID: xcjing,BEA 资深技术顾问,加入BEA中国多年,在门户技术、RFID解决方案上有着丰富的经验。
