我正在尝试使用Liferay共享会话属性。
我想基于以下代码,在不同URL的不同WAR文件中的两个不同portlet上使用相同的属性:
Liferay 7 not able to set the global session attribute
我要保存的值:单个字符串
在portlet 1中设置:
String sharedKey = "LIFERAY_SHARED_" + key;
HttpSession session = PortalSessionThreadLocal.getHttpSession();
session.setAttribute(sharedKey, bean);
Portlet 1可以保留,重置和使用精细属性。
阅读portlet 2:
key = "LIFERAY_SHARED_" + key;
HttpSession session = PortalSessionThreadLocal.getHttpSession();
Object bean = session.getAttribute(key);
此值始终为空。
两个portlet都是Spring MVC portlet。
两个portlet都具有:
<instanceable>false</instanceable>
<private-session-attributes>false</private-session-attributes>
<requires-namespaced-parameters>false</requires-namespaced-parameters>
在他们的liferay portlet XML-s中。
这两个portlet都扩展了org.springframework.web.portlet.DispatcherPortlet。
Liferay版本:
Liferay DXP Digital Enterprise 7.0.10 GA1
任何帮助将不胜感激。 让我知道是否有人需要澄清。
非常感谢, 朋友
答案 0 :(得分:2)
Kyle Stiemann最近在portlet中编写了nice article on using sessions。 TL; DR:您正在使用带有前缀"LIFERAY_SHARED_"
的HttpSession,但是应该使用Portlet会话:这是Liferay所管理的,HttpSession可能是“模拟的”,例如它可能不是tomcat管理的对象。
引用他的文章中的一种选择:
使用Liferay session.shared.attributes前缀(例如 LIFERAY_SHARED_)之间共享一个或多个会话属性 不同应用程序/ WAR中的portlet。
Liferay根据以下内容向所有portlet公开某些会话属性 某些前缀值。尽管这些前缀可以通过配置 portal-ext.properties,我建议使用默认前缀之一: LIFERAY_SHARED _。
例如:
// Portlet A portletRequest.getPortletSession(true) .setAttribute("LIFERAY_SHARED_" + CONSTANTS.ATTR_NAME, "value", PortletSession.APPLICATION_SCOPE); // Portlet B (in a different WAR) String attrValue = portletRequest.getPortletSession(true) .getAttribute("LIFERAY_SHARED_" + CONSTANTS.ATTR_NAME, PortletSession.APPLICATION_SCOPE);
优点:
- 仅将必要的属性公开给其他Portlet(而不是公开整个会话)。
缺点:
- 将会话属性公开给所有portlet。
- 紧密耦合,而没有指出其他portlet可能正在使用此数据。
- 共享会话数据的非标准方法。
请注意强烈建议仅使用原始类型作为会话属性。消除了对自定义序列化和类加载问题的需求。另外请注意,这里需要getPortletSession
的变体和附加范围参数。
但是,尽管从技术上讲,它可以为您的问题提供答案,但您也想阅读"Session Storage is Evil"。
TL; DR:请勿使用上述技术。而是消除会话的使用。