Portal開源實現-Liferay的Portlet Session處理(
系統
1709 0
二、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);
????????}
????}
?
Portal開源實現-Liferay的Portlet Session處理(2)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元