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