Portal开源实现-Liferay的Portlet Session处理(2)

session

二、LIFERAY中的实现

LIFERAY在构建ActionRequestImpl和RenderRequestImpl时,会设置PORTLET SESSION,如下代码所示:public RenderRequestImpl(HttpServletRequest req, Portlet portlet,        CachePortlet cachePortlet,        PortletContext portletCtx,        WindowState windowState, PortletMode portletMode,        PortletPreferences prefs, String layoutId) {   ...  _req = dynamicReq;  _portlet = portlet;  _cachePortlet = cachePortlet;  _portalCtx = new PortalContextImpl();  _portletCtx = portletCtx;  _windowState = windowState;  _portletMode = portletMode;  _prefs = prefs;  _ses = new PortletSessionImpl(   _req.getSession(), _portletName, _portletCtx);   ... }从兰色的部分(  _ses = new PortletSessionImpl(_req.getSession(),_portletName, _portletCtx);  )我们可以看到,这个PORTLET SESSION其实就是PORTAL SYSTEM的 SESSION 对象。所以无论request调用getSession()或者getPortletSession()都将获取Portal 系统的SESSION 对象,而无论该PORTLET  是或者不是属于PORTAL SYSTEM上下文。而且即使不同PORTAL APPLICATION的PORTLET也将使用同一个SESSION 对象(PORTAL 系统)。也就是说,对于某一个PORTLET来说,如果有对其的SESSION进行的操作,并没有真正的在该APPLICATION上下文中的SESSION进行操作,而是在PORTAL系统上下文的SESSION中进行操作。

而且LIFERAY提供getPortletSession来获取PortletSession对象,而不是getSession()方法,所以即使getPortletSession()可以获取正确的Session对象,开发人员由于习惯问题,也因使用getSession()而得不到。

另外如果调用request.getSession(true)还可能会出现错误,因为LIFERAY在包含某一个PORTLET内容是,调用PortletRequestDispatcherImpl.include()方法,该方法将生成PortletServletRequest 和PortletServletResponse,请见如下代码:

PortletServletRequest portletServletReq = new PortletServletRequest(    httpReq, reqImpl, pathInfo, queryString, requestURI,    servletPath);

   PortletServletResponse portletServletRes =    new PortletServletResponse(     resImpl.getHttpServletResponse(), resImpl);而PortletServletRequest的构造函数是如下定义的:public PortletServletRequest(HttpServletRequest req,         RenderRequest renderRequest, String pathInfo,         String queryString, String requestURI,         String servletPath) {

  super(req);

  _ses = req.getSession();  _renderRequest = renderRequest;  _pathInfo = pathInfo;  _queryString = queryString;  _requestURI = requestURI;  _servletPath = servletPath; }所以其SESSION依然是PORTAL系统上下文的。然后问题就出在这里,PortletServletRequest实现了getSession()方法,但是没有实现getSession(boolen create)方法,如果用户在此阶段调用getSession(true)的话,在某些情况下就会抛出NullPointerException

原因见如下代码(请注意我添加的注释部分)//ApplicationHttpRequest:  

 public HttpSession getSession(boolean create) {

        if (crossContext) {                        // There cannot be a session if no context has been assigned yet            if (context == null)                return (null);

            // Return the current session if it exists and is valid            if (session != null)                return (session.getSession());     // 我的注释:这里将获取PORTAL系统的SESSION对象。            HttpSession other = super.getSession(false);            if (create && (other == null)) {                // First create a session in the first context: the problem is                // that the top level request is the only one which can                 // create the cookie safely                other = super.getSession(true);            }            if (other != null) {                Session localSession = null;                try {                    // 我的注释:this context did not have the session with session id. It can just be found in the Portal                    // context. So here it will return a null value.                    localSession =                        context.getManager().findSession(other.getId());                    localSession.access(); //我的注释:Here, localSession is null. So it throws a NullPointException.                } catch (IOException e) {                    // Ignore                }                if (localSession == null) {                    localSession = context.getManager().createEmptySession();                    localSession.setNew(true);                    localSession.setValid(true);                    localSession.setCreationTime(System.currentTimeMillis());                    localSession.setMaxInactiveInterval                        (context.getManager().getMaxInactiveInterval());                    localSession.setId(other.getId());                }                session = localSession;                return session.getSession();            }            return null;

        } else {            return super.getSession(create);        }

    }

时间: 2024-12-20 23:56:08

Portal开源实现-Liferay的Portlet Session处理(2)的相关文章

Portal开源实现-Liferay的Portlet Session处理(1)

session 一.规范中的SESSION描述 (PortletSession objects must be scoped at the portlet application context level. Each portlet application has its own distinct PortletSession object per user session. The portlet container must not share the PortletSession obj

Liferay中portlet.xml中安全控制

在portlet中都有portlet.xml,我们都可以看到下面关于安全设定对应的代码: .. <security-role-ref> <role-name>administrator</role-name> </security-role-ref> <security-role-ref> <role-name>guest</role-name> </security-role-ref> <securit

portal学习(二)portlet开发之hello world

portal开发的一个重要工作就是portlet的开发,网上一大堆hello world,都是最简单的,用PrintWriter输出字符串.今天介绍一下稍微复杂的,用户转到portlet的edit Model,该页面是有一个输入框和一个按钮,输入你的名字,然后提交,将转到此portlet的view Model并输出hello,your name.     portlet与servlet非常相似,因为portlet就是在servlet规范的基础上扩展的,并且portlet容器也是在servlet容

Liferay Portal额外研究(三):IFrame Portlet地session丢失疑难处理

       Liferay提供了一种非常的简单web应用整合和单点登陆的方式:Iframe Portlet.利用Iframe Portlet可以很容易将一个已经存在的web应用纳入,并且支持利用form的post或get方式,实现用户的登陆.          对于Liferay这样的机制没有任何问题,实现的也非常巧妙:但是对于很多web应用系统来说,使用Liferay IFrame Portlet的form方式实现登陆后,虽然可以成功登陆,但是在显示的新页面中,却发现用户信息丢失,或者更准确

关于 liferay portlet

问题描述 关于 liferay portlet liferay 和 portlet 是一个技术还是两个?我在网上搜有liferay教程,也有portlet教程 究竟该学那个 解决方案 liferay是一种可以装载pirtlet的容器,你可以根据需要去选择

值的关注的Java开源项目(原创)

项目|原创 值的关注的Java开源项目   名称 资料 概况 OFBiz http://ofbizchina.com:8080/ http://www.ofbiz.org/ https://ofbiz.dev.java.net/ OFBiz是一个非常著名的开源项目,提供了创建基于最新J2EE/XML规范和技术标准,构建大中型企业级.跨平台.跨数据库.跨应用服务器的多层.分布式电子商务类WEB应用系统的框架.     OFBiz最主要的特点是OFBiz提供了一整套的开发基于Java的web应用程序

Liferay激活Navigation和Breadcrumb

这个问题居然卡了我1个多小时,主要开始想复杂了. 因为默认如果给网站做站内导航时,我们都是用js实现的,而Liferay的页面又那么复杂,因为portal页面都由一个portlet组成的,每个页面id构成也很复杂,所以一直搞了我很久没弄出来,直到我回归了Portal的基本定义. 在Portal定义中,一个非常主要的功能是内容聚合 "content aggregation",所以,聚合功能应该是框架本身就帮你做好了,我们需要做的仅仅是定义页面(而不是编写页面,页面框架帮你搞定了),然后进

Windows Server 2008部署Portal系统指南(二)

六. Windows 2008 server 配置Liferay Portal 步骤 1 Liferay Portal版本的选择 Liferay支持的J2EE包括: Geronimo+Tomcat Glassfish JBoss+Jetty 4.0 JBoss+Tomcat 4.0 JBoss+Tomcat 4.2 Jetty JOnAS+Jetty JOnAS+Tomcat Pramati Resin Tomcat 5.5 for JDK 1.4 Tomcat 5.5 for JDK 5.0

Liferay Plugin SDK开发与Ext开发的选择

Liferay有两种服务: 1)internal services      即Liferay核心服务,比如portal-impl.jar 2)external services     即Portal的API,比如portal-kernel.jar以及portal-service.jar Liferay的internal服务更新频繁,升级Liferay版本时尤其要注意:而Liferay的external服务则相当稳定. Ext开发可以同时使用internal服务和external服务.且Lif