This wiki does not contain official documentation and is currently deprecated and read only. Please try reading the documentation on the Liferay Developer Network, the new site dedicated to Liferay documentation. DISCOVER Build your web site, collaborate with your colleagues, manage your content, and more. DEVELOP Build applications that run inside Liferay, extend the features provided out of the box with Liferay's APIs. DISTRIBUTE Let the world know about your app by publishing it in Liferay's marketplace. PARTICIPATE Become a part of Liferay's community, meet other Liferay users, and get involved in the open source project. Portlet间的通信
介绍
在Portlet规范的第一个版本( JSR-168/Portlet 1.0)是不包含任何内部Portlet通信支持的。在第二个版本(JSR-286/Portlet 2.0)提供了IPC 通信的支持.
而JSR-286让两个portlet之间分享数据变得简单。通过使用IPC机制,我们可以在 Action层到View层 或View 层到View 层 中分享数据。
有3中方式可以在2个portlet之间分享数据:
- Portlet session
- IPC Mechanisms
- Public Render Parameters
- Event
- Client-Side IPC
- Cookies
1. Portlet Session #
默认的情况下,每个不同的War都有他们各自的seesion,但是是不能被分享给其他War的。
而Liferay 提供了一个允许夸War包访问的分享Session属性的机制。
每个Portlet应用程序都会创建一个PortletSession供每个用户使用。
在相同的Portal应用程序中,PortletSession是非常有用的,可以用在联系不同Porlet间相关联的用户信息。
步骤1:设置下面的属性 在 Portlet1 中 #
liferay-portlet.xml
<portlet>
<private-session-attributes>false</private-session-attributes>
</portlet>#
步骤2:设置Seesion #
PortletSession session = renderRequest.getPortletSession();
session.setAttribute("sessionValue", some-value ,PortletSession.APPLICATION_SCOPE);#
步骤3:在Portlet2中获取 Seesion中的值 #
PortletSession ps = renderRequest.getPortletSession();
String tabNames = (String)ps.getAttribute("sessionValue ",PortletSession.APPLICATION_SCOPE);#
2,内部Porlet连接(IPC)机制 #
2.1 Public-Render-Parameter Inter-portlet Communication #
在JSR 168,processAction里设置的Render Parameter 只能供同一Portlet的Render来使用。
通过使用 Public Render Parameter ,在一个Porlet中的processAction里设置的 Public Render Parameter 也可以能供其他的Portlet的Render使用了。
在portal-ext.properties里添加下面的属性,我们可以使不同页面中的Portlet互相分享其 Render的状态:
portlet.public.render.parameter.distribution=ALL_PORTLETS
#
步骤1:在“Sender-Portlet”中添加下面的属性 #
<portlet-app>
<portlet>
<supported-public-render-parameter>id1</supported-public-render-parameter>
</portlet>
<public-render-parameter>
<identifier>id1</identifier>
<qname xmlns:x="http://abc.com/userId">x:param1</qname>
</public-render-parameter>
</portlet-app>Note:We can declare a list of public paramters for a portlet application.
注意:我们可以为Portlet声明一个 Public Render Parameter 列表。
#
步骤2 #
我们可以在processAction方法中设置 Public Render Parameter 。作为key,我们使用的是定义好了的 Public Render Parameter 标识符:
response.setRenderParameter("id1", "someIdValue");
E.g.
public void processAction(ActionRequest request, ActionResponse response) throws IOException, PortletException {
........
response.setRenderParameter("id1", “someIdValue”); ........
}#
步骤3:“Receiver Portlet”的“portlet.xml”文件 #
在porltet定义中指定哪个 Public Render Parameter 允许被分享
<portlet-app>
<portlet>
<portlet-name >PortletB< /portlet-name>
<supported-public-render-parameter>id1</supported-public-render-parameter>
</portlet >
<public-render-parameter>
<identifier>id1</identifier>
<qname xmlns:x="http://abc.com/userId">x:param1</qname>
</public-render-parameter>
</portlet-app>#
步骤4 #
Portlet可以通过使用 request.getPublicParameterMap() 方法读取 Public Render Parameter 。
注意:因为 Public Render Parameter 被合并到全局 parameter中了,所以我们也可以用下面的方法去读取:
request.getParameter(“id1”);
#
步骤5 #
我们也可以使用下面的方法去移除一个 Public Render Parameter :
response.removePublicRenderParameter("id1")2.2 Event Inter-portlet Communication # #
Portlet Event 可以被接收和传递。
在JSR-168中,实现 Eventing(事件)的唯一方法是通过Portlet Session.这种方法的限制是,要求Portlet都隶属于相同的Web 应用。
在JSR-286里,则为 Event定义里生命周期。所以使属于不同Web应用的portlets间的事件成为了可能。
在portal-ext.properties文件中添加下面的属性,这样我们就可以在不同页面间传递或接收来自其他Portlet的Event了。
portlet.event.distribution=ALL_PORTLETS
#
步骤1:Sender Portlet #
portlet.xml
Porltet协议定义了一种方法去告知一个portlet容器如何去负责发送一个Event。
添加如下的字段到<portlet>标签里:
<portlet-app>
<portlet>
<supported-publishing-event xmlns:x='http://liferay.com'>
<qname>x:empinfo</qname>
</supported-publishing-event>>
</portlet>
<event-definition xmlns:x='http://liferay.com'>
<qname>x:empinfo</qname>
<value-type>java.lang.String</value-type>
</event-definition>
</portlet-app>#
步骤2:在Process Action中设置一个Event #
javax.xml.namespace.QName qName = new QName("http://liferay.com", "empinfo", "x");
response.setEvent(qName, "Hi! You have received Event Data sent from Sender Portlet");#
步骤3:Listener Portlet #
portlet.xml
<portlet-app>
<portlet>
<supported-processing-event xmlns:x='http://liferay.com'>
<qname>x:empinfo</qname>
</supported-processing-event>
</portlet>
<event-definition xmlns:x='http://liferay.com'>
<qname>x:empinfo</qname>
<value-type>java.lang.String</value-type>
</event-definition>
</portlet-app>#
步骤4:获取Event #
如下图所示,Event将在processAction之后被执行。
Lifecycle for IPC Event
IPC Event 的生命周期
@javax.portlet.ProcessEvent(qname = "{http://liferay.com}empinfo")
public void handleProcessempinfoEvent(javax.portlet.EventRequest request, javax.portlet.EventResponse response)
throws javax.portlet.PortletException, java.io.IOException {
javax.portlet.Event event = request.getEvent();
String value = (String) event.getValue();
System.out.print("value in process event>>>>>>>>>" + value);
response.setRenderParameter("empInfo", value);
}2.3 Client-Side IPC #
目前,有两个关于客户端IPC 的 API
Event生成
Liferay.fire(
'<eventName>', {
name: value
}
);E.g.
Liferay.fire(
'planTravel', {
origin: 'pune',
destination : 'mumbai'
}
);Event监听
Liferay.on(
'<eventName>',
function(event) {
// your code
}
);E.g.
Liferay.on(
'<eventName>',
function(event) {
showNews('', event.origin);
showNews('', event.destination);
}
);#
3. Cookies #
除了IPC机制外,还有一种最简单的方法:通过Cookies。获取不同页面间不同的Porltet的数据。
但是这种方法还有一些局限性:
1. 不允许超过4KB的数据
2.每个服务器限制了最多只能有20个Cookies。
所以说,很不推荐去把每个变量分别存成不同的Cookie。
#
Portlet 1 #
通过JQuery设置Cookies
<script src="/html/js/jquery/cookie.js" type="text/javascript" > </script>
function setCookie(docURL) {
jQuery.cookie("cookieParam",docURL);
}
设置Java/JSP 设置Cookies
HttpServletResponse response = PortalUtil.getHttpServletResponse(actionResponse);
Cookie cookieParam = new Cookie("cookieParam ", password);
response.addCookie(cookieParam);#
Portlet 2 #
通过JQuery获取Cookies
jQuery.cookie("cookieParam ");
通过Java/JSP获取Cookies
String sessionid = "";
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("cookieParam ")) {
sessionid = cookies[i].getValue();
break;
}
}
}