程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Portal開源實現-Liferay的Portlet Session處理(2)

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

編輯:關於JAVA

二、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); }

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved