天天看點

Liferay Portal額外研究(三):IFrame Portlet地session丢失疑難處理

       liferay提供了一種非常的簡單web應用整合和單點登陸的方式:iframe portlet。利用iframe portlet可以很容易将一個已經存在的web應用納入,并且支援利用form的post或get方式,實作使用者的登陸。

       對于liferay這樣的機制沒有任何問題,實作的也非常巧妙;但是對于很多web應用系統來說,使用liferay iframe portlet的form方式實作登陸後,雖然可以成功登陸,但是在顯示的新頁面中,卻發現使用者資訊丢失,或者更準确的說,是session丢失。

       其實,這種現象跟liferay關系不大,而是應用本身決定的。事實上,所有的portal context的iframe 方式,都有可能發生這個情況。

       因為很多web應用系統,在執行login操作的後,習慣性的選擇redirect操作,這樣會強制浏覽器中的顯示位址變更為轉移的位址。事實上這是個很正确的做法,在正常境況下,不會有任何問題,而且還可以很好的防止頁面重新整理等所帶來的問題。

       但是在liferay的iframe portlet中,web應用這樣的redirect操作,造成了調轉到新頁面後,session變成了一個新的,進而造成放置在原有session中的login user資訊丢失。

       跟蹤并做了如下的一組測試(liferay和webapp在不同的jvm環境下):

應用 位置 session id

(liferay) 執行form post前 d03e1b828395ef5bcb1063a8290bd254

(app_a) login操作 397bb3656e2a12a96ce3f16e0a89c607

(app_a) 登陸後的新頁面 58a1054c6ede4a7d6cfa2fcdbb3e0736

       從上面可以明顯看出來,redirect之後,web應用的新頁面産生了新的sessionid      

       解決這個問題,有兩種方式,這兩種方式都依賴于被liferay portlet納入的web應用自身。

       方式一:login操作後,不采用redirect方式,而是dispatcher方式。

       方式二:login操作後,依然采用redirect方式,但将目前的jsessionid賦予新的頁面。

dispatcher方式:

servletcontext sc = getservletcontext();

requestdispatcher rd = null;

rd = sc.getrequestdispatcher("/index.jsp");

rd.forward(request, response);

redirect方式(保持同一個session):

response.sendredirect(“ index.jsp;jsessionid=397bb3656e2a12a96ce3f16e0a89c607”)

       有一種情況下,無所謂是否采用redirect方式,這就是在liferay和webapp在同一個jvm環境下。