2014-01-13 33 views
1

我想在一個portlet實例的所有用戶之間共享bean,但我不知道如何。如何在Portlet實例的所有用戶之間共享數據?

我正在研究一個(Liferay)portlet,它將有許多對此portlet實例的每個用戶有用的數據:在被放置在頁面上後,portlet將從DB中獲取取決於其偏好的數據。我希望此portlet將此數據存儲在RAM中,而不是在首選項中以避免從/到字符串轉換。

我知道我可以將它存儲在會話中,但這會爲每個查看portlet的用戶創建一份數據副本。結果:因爲這個,我可能在RAM中有大量的數據。 我無法使用上下文(或我的Portlet類中的局部變量),因爲數據將在Portlet的所有實例之間共享,並且我希望它是特定於實例的。

事實上,我希望它的工作方式與portlet的首選項相似,但其他bean不是Strings。

這裏是我想什麼(話說我的Portlet顯示的內容列表,就像資源發佈)的例子:

  • 在一個頁面上,我會放2次的portlet:一個顯示所有的事件,另一個顯示所有的博客條目
  • 被設置首選項後,portlet的每個實例都將獲得內容的列表,並且將其存儲在RAM
  • 當用戶訪問該頁面時,列表將使用每個Portlet實例的內容
  • 當另一個用戶訪問同一頁面,將使用相同的列表(由「同一名單」,我的意思是列表的同一個實例,對於爲例)

這裏Portlet類的代碼示例:

package com.test; 

import com.liferay.portlet.asset.model.AssetEntry; 
import com.liferay.util.bridges.mvc.MVCPortlet; 

import java.io.IOException; 
import java.util.List; 

import javax.portlet.PortletException; 
import javax.portlet.RenderRequest; 
import javax.portlet.RenderResponse; 

/** 
* Portlet implementation class NewPortlet 
*/ 
public class NewPortlet extends MVCPortlet { 
    @Override 
    public void doView(RenderRequest renderRequest, 
      RenderResponse renderResponse) throws IOException, PortletException { 

     List<AssetEntry> entries = null; 

     /*HERE : Get the entries from RAM (session/context/...)*/ 

     renderRequest.setAttribute("entries", entries); 

     super.doView(renderRequest, renderResponse); 
    } 
    /*HERE : The methods containing code for preferences, setting "entries" to RAM, etc...*/ 
} 

有誰知道如何去做,或者如果它不可能?

+0

你對RAM存儲器有什麼意義?把你的代碼放到問題中。 – Mark

+0

通過RAM,我的意思是Randow訪問存儲器(不是ROM,所以不是用HD寫的)。 OK for Code,我會嘗試一個例子(我還沒有代碼,因爲如果沒有這個問題的解決方案,我就無法開始編碼)。 – pierreonthenet

+0

我可能已經找到了解決方案:使用上下文並在屬性名稱中包含portlet名稱空間。 它看起來像這樣: entries = context.getAttribute(renderResponse.getNamesSpace()+「entries」); 您對此有何看法? – pierreonthenet

回答

0

我認爲更好的方法是將portlet特定數據置於portlet首選項。您可以配置佈局特定的portlet偏好:

放至liferay-portlet.xml

Set <preferences-unique-per-layout> false</preferences-unique-per-layout> 

詳情見的liferay-portlet.dtd描述:

<!-- 
Set the preferences-unique-per-layout value to true if the preferences for the 
portlet are unique across all pages. If set to false, the preferences for the 
portlet are shared across all pages. The default value is true. 

The preferences-unique-per-layout element is used in combination with the 
preferences-owned-by-group element. See the comments for the 
preferences-owned-by-group element for more information. 
--> 
+0

謝謝你的回答。 使用偏好設置,我認爲我們不能存儲其他字符串。我對嗎 ?我認爲這對於演出來說不會太好。 並設置「preferences-unique-per-layout」爲「false」對我來說不是問題?如果首選項爲所有實例共享,則不會滿足我的需求。 – pierreonthenet

+0

是的,你需要設置'preferences-owned-by-group'爲'true'參見http://docs.liferay.com/portal/4.2/official/liferay-portlet-development-guide-4.2/multipage/ch02 .html – Mark

+0

好的,但是這樣做,我如何在首選項中存儲Bean,因爲PortletPreferences.setValue()只接受參數中的2個字符串? – pierreonthenet

1

通過所有評論的閱讀能力,你的需求來存儲RAM中的數據,這聽起來很像我的初步優化。

你是否這樣做是因爲你已經測量了從其他來源讀取數據的影響?如果你在這裏討論Liferay Entities(博客文章等),那麼它們實際上是緩存的:如果你通過API檢索它們,你很可能不會訪問數據庫,但只是訪問緩存,而不需要保留它們在內存中並且有可能丟失對基礎數據的後續更改。另外,如果你不是指Liferay實體,你確定這是一個應該在portlet級別解決的問題嗎?如果您有「業務級別」數據,您可能希望將它們放入業務層(可能已緩存),並只需通過Id引用它們即可 - 並且這些Id可輕鬆存儲在Portlet首選項中。

技術信息:

由於portlet首由門戶存儲 - 只爲指定字符串(實際豆會引發各種問題的類加載) - 你說的沒錯與侷限性這種類型。任何你想堅持超越絃樂的東西都必須由你自己來處理。最有可能 - 正如我上面所說 - 這最適合業務層,而不是用戶界面。

+0

謝謝你的回答! 這是初步的優化,我同意。 這對於我的portlet偏好來說,主要是一種「緩存」。這只是技術數據,這裏沒有業務。根據首選項中的數據,我計算了一些對我的portlet有用的bean。這些bean的計算取決於門戶網站中的內容,並且我不希望在每次查看portlet時都會這樣做,因爲它需要花費時間。由此產生的bean並不是很大,但我不想將這些數據存儲在首選項中(我不想分析它)。 – pierreonthenet

相關問題