在JSR168规范中,允许使用preferences来存储portlet的一些初始信息,preferences的内容在portlet.xml来设置.
在liferay中,对preferences加入了数据库持久化功能,并且可针对company, layout, portlet instance和user的不同组合来定制.
首先来看看在jsp页面上如何访问preferences.
/html/portal/render_portlet.jsp - Portlet输出页面。
Portlet portlet = (Portlet)request.getAttribute(WebKeys.RENDER_PORTLET);
CachePortlet cachePortlet = PortletInstanceFactory.create(portlet, application);
// 读取preferences.
PortletPreferences portletPrefs = PortletPreferencesLocalServiceUtil.getPreferences(
company.getCompanyId(), PortletPreferencesFactory.getPortletPreferencesPK(request, portletId));
// 创建PortletConfig.
PortletConfig portletConfig = PortletConfigFactory.create(portlet, application);
PortletContext portletCtx = portletConfig.getPortletContext();
HttpServletRequest originalReq = PortalUtil.getOriginalServletRequest(request);
// 创建RenderRequest.
RenderRequestImpl renderRequestImpl = RenderRequestFactory.create(
originalReq, portlet, cachePortlet, portletCtx, windowState, portletMode, portletPrefs, plid);
StringServletResponse stringServletRes = new StringServletResponse(response);
// 创建RenderResponse.
RenderResponseImpl renderResponseImpl = RenderResponseFactory.create(
renderRequestImpl, stringServletRes, portletId, company.getCompanyId(), plid);
// setAttribute(WebKeys.JAVAX_PORTLET_CONFIG, portletConfig);
// setAttribute(WebKeys.JAVAX_PORTLET_REQUEST, renderRequestImpl);
// setAttribute(WebKeys.JAVAX_PORTLET_RESPONSE, renderResponseImpl);
renderRequestImpl.defineObjects(portletConfig, renderResponseImpl);
if (portlet.isActive() && access) {
try {
cachePortlet.render(renderRequestImpl, renderResponseImpl);
}
catch (UnavailableException ue) {
portletException = true;
PortletInstanceFactory.destroy(portlet);
}
}
PortletPreferencesPK 为preferences的主键,它由portletId, layoutId和ownerId三部分标识.
com.liferay.portal.service.impl.PortletPreferencesLocalServiceImpl
// getPreferences.
public javax.portlet.PortletPreferences getPreferences(
String companyId, PortletPreferencesPK pk)
throws PortalException, SystemException {
// 读取prefs缓存.
Map prefsPool = PortletPreferencesLocalUtil.getPreferencesPool(
pk.ownerId);
PortletPreferencesImpl prefs =
(PortletPreferencesImpl)prefsPool.get(pk);
if (prefs == null) {
PortletPreferences portletPreferences = null;
// 读取portlet.
Portlet portlet = PortletLocalServiceUtil.getPortletById(
companyId, pk.portletId);
try {
// 从数据库里读preferences.
portletPreferences =
PortletPreferencesUtil.findByPrimaryKey(pk);
}
catch (NoSuchPortletPreferencesException nsppe) {
portletPreferences = PortletPreferencesUtil.create(pk);
if (portlet == null) {
// 设置系统默认的preferences.
portletPreferences.setPreferences(
Portlet.DEFAULT_PREFERENCES);
}
else {
// 设置portlet.xml中定义的preferences.
portletPreferences.setPreferences(
portlet.getDefaultPreferences());
}
PortletPreferencesUtil.update(portletPreferences);
}
prefs = PortletPreferencesSerializer.fromXML(
companyId, pk, portletPreferences.getPreferences());
prefsPool.put(pk, prefs);
}
return (PortletPreferencesImpl)prefs.clone();
}
上面的代码首先从缓存中读取,如没有则从数据库读取,
如数据库中还没有相应的记录,则读取默认值并更新到数据库中.
PortletPreferencesFactory
另外一个获取preferences的方式是通过PortletPreferencesFactory,它提供了更方便的获取preferences的方法.
getPortalPreferences(HttpServletRequest req); // 通过HttpServletRequest获取
getPortalPreferences(ActionRequest req); // 通过ActionRequest获取
getPortalPreferences(RenderRequest req); // 通过RenderRequest获取
在getPortalPreferences方法中,读取preferences的任务还是交给PortletPreferencesLocalServiceImpl,
只是在没有登录时,preferences被存储在httpsession中以便共享.
getPreferences(HttpServletRequest req);
与上面三个方法不同,这个方法直接读取RenderRequest的preferences.
getPreferencesValidator(Portlet portlet);
获取preferences的验证对象.
liferay中proferences的保存.
在liferay中,调用preferences的store就可以保存proferences到数据库了,
public void store() throws IOException, ValidatorException {
Portlet portlet = PortletLocalServiceUtil.getPortletById(
_companyId, _pk.portletId);
if (!_pk.portletId.equals(PortletKeys.LIFERAY_PORTAL)) {
PreferencesValidator prefsValidator =
PortalUtil.getPreferencesValidator(portlet);
// 验证数据
if (prefsValidator != null) {
prefsValidator.validate(this);
}
}
// 更新preferences
PortletPreferencesLocalServiceUtil.updatePreferences(_pk, this);
}
proferences是以xml文档的方式存入数据库中的.