Portal開源實現-Liferay的Portlet Session處理(2)

來源:互聯網
上載者:User
二、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);
        }

    }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.