How to share data between all users of a portlet instance?

南楼画角 提交于 2019-12-11 07:17:49

问题


I would like to share beans between all users of a portlet instance but I don't know how.

I am working on a (Liferay) portlet that will have many data useful for every users of an instance of this portlet : after being placed on a page, the portlet will get data from DB that depends on its preferences. I would like this portlet to store this data in RAM and not in preferences to avoid conversion from/to String.

I know I can store it in session, but this will create a copy of the data for each user viewing the portlet. Result : I could have a huge amount of data in RAM because of this. I can't use the context (or a local variable in my Portlet class) because the data would be shared between all instances of the portlet, and I want it to be specific for an instance.

In facts, I would like to have it working just like the preferences of the portlet, but with other beans than Strings.

Here is an example of what I would like (saying my portlet is displaying a list of contents, just like the Asset Publisher) :

  • On a page, I would place 2 times the portlet : one displaying all the events and another displaying all the blogs entries
  • After the preferences being set, each instance of the portlet would get a list of contents and will store it in RAM
  • When a user is visiting the page, the list of contents of each portlet instance would be used
  • When another user is visiting the same page, the same list would be used (by "same list", I mean the same instance of List, for exemple)

Here an example of code for Portlet class:

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...*/
}

Does anyone knows how to do it, or if it's impossible?


回答1:


Reading through all of the comments and your demand to store the data in RAM, this sounds a lot like preliminary optimization for me.

Are you doing this because you have measured the impact of reading the data from other sources? If you're talking about Liferay Entities here (blog posts etc) then they're actually cached: If you retrieve them through the API, you'll most likely not hit the database but just access the cache anyways, without any need to keep them in memory and risk to loose subsequent changes to the underlying data.

Also, in case you're not referring to Liferay entities, are you sure that this is a problem that should be solved on the portlet level? If you have "business level" data, you might want to have them in your business layer (maybe cached) and just refer to them by Ids - and these Ids would easily be stored in portlet preferences.

Technical information:

As portlet preferences are stored by the Portal - and specified only for Strings (real beans would trigger all kinds of classloading issues) - you're right with the limitations to this type. Anything you want to persist beyond Strings has to be handled by you yourself. And most likely - as I said above - this suits best for the business layer, not the UI.




回答2:


I think the better way is to put the portlet specific data to the portlet preferences. You can config the layout specific portlet preferences:

put to liferay-portlet.xml:

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

For details see description of 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.
-->


来源:https://stackoverflow.com/questions/21087613/how-to-share-data-between-all-users-of-a-portlet-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!