我根据用户使用的结构链接一个类别。例如:我的结构是" A"那么使用这种结构创建的任何内容都应该具有类别为" A"。
我已经在BaseModelListener
模型上创建了一个扩展JournalArticle
的侦听器。我重写onBeforeUpdate()
看起来像:
@Override
public void onBeforeUpdate(JournalArticle aModel) throws ModelListenerException {
try {
long[] assetCategoryIds = refactorCategories(anArticle); // this reads the structure key and updates the list of category to the correct one.
String[] assetTagNames = getTags(anArticle);
long[] assetEntryLinkIds = getEntryLinkIds(anArticle);
JournalArticleLocalServiceUtil.updateAsset(anArticle.getUserId(), anArticle, assetCategoryIds, assetTagNames, assetEntryLinkIds);
} catch (PortalException |SystemException ex) {
throw new ModelListenerException("Cannot update the categories for articleId" + anArticle.getArticleId(), ex);
}
}
我使用一组业务规则更正了categoryIds
。
以下是两种可能的情况:
没有分配类别:
onBeforeUpdate()
就像一个魅力,并且分配了正确的类别。如果用户在调用之前分配了一个类别(可能是错误的类别):
onBeforeUpdate()
实现并且我能够看到更新的资产(使用调试验证),但是当完成整个过程时,Web内容不会反映正确的类别。我的理解:
调用updateAsset
时,它会更改类别。但是当Hibernate保存内容时,它会保存用户选择的类别。这对我来说似乎有点奇怪。
所以我希望检查是否有可能使用的解决方案或API。
此外,我尝试了onAfterCreate()
,onAfterUpdate()
,onBeforeCreate()
,但没有运气。
我相信我可以挂钩JournalArticleService
但我希望尽可能使用听众来做这件事。
根据Tobias建议更新了代码:
@Override
public void onBeforeUpdate(JournalArticle aModel) throws ModelListenerException {
ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();
try {
long[] assetCategoryIds = refactorCategories(anArticle); // this reads the structure key and updates the list of category to the correct one.
if (serviceContext != null) {
serviceContext.setAssetCategoryIds(assetCategoryIds);
}
} catch (PortalException |SystemException ex) {
throw new ModelListenerException("Cannot update the categories for articleId" + anArticle.getArticleId(), ex);
}
}
答案 0 :(得分:1)
请参阅JournalArticleLocalServiceImpl.addArticle()
resp。 updateArticle()
:
journalArticlePersistence.update(article);
...
updateAsset(userId, article, serviceContext.getAssetCategoryIds(),
serviceContext.getAssetTagNames(),
serviceContext.getAssetLinkEntryIds());
第一行journalArticlePersistence.update(article)
将调用您的侦听器,而updateAsset
将保存用户提供的类别。在给你的听众打电话之后。
您可以获取当前服务上下文并从侦听器内部进行更改:
ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();
if (serviceContext != null) {
serviceContext.setAssetCategoryIds(assetCategoryIds);
}
答案 1 :(得分:1)
我建议创建一个hook插件并使用服务包装器来扩展JournalArticleLocalService
。我找到一个更适合任务的服务钩子。根据Liferay认证计划,通过服务挂钩执行此操作也是首选方法。
一般来说:
示例扩展服务:
public class MyJournalArticleLocalService extends JournalArticleLocalServiceWrapper {
@Override
public JournalArticle addArticle(..., ServiceContext serviceContext) throws PortalException, SystemException {
// set the right category in the service context, as the service context
// that the original service will work with can be modified here
serviceContext.setAssetCategoryIds(refactorCategories(...));
// delegate to the original implementation
return super.addArticle(..., serviceContext);
}
@Override
public JournalArticle updateArticle(..., , ServiceContext serviceContext) throws PortalException, SystemException {
// set the right category in the service context, as the service context
// that the original service will work with can be modified here
serviceContext.setAssetCategoryIds(refactorCategories(...));
// delegate to the original implementation
return super.updateArticle(..., serviceContext);
}
}
使用服务挂钩,您可以在 Liferay完成持久化文章并创建/更新相关资产条目之后或之前更新类别。
您可以在liferay-hook.xml
描述符中注册服务挂钩:
<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">
<hook>
<service>
<service-type>com.liferay.portlet.journal.service.JournalArticleLocalService</service-type>
<service-impl>com.test.MyJournalArticleLocalService</service-impl>
</service>
</hook>