Liferay 7中JournalArticleLocalServiceUtil无法返回articleDisplay内容
解决Liferay 7 GA5中Portlet编程访问Web内容的articleDisplay问题
我来帮你搞定这个问题——在Liferay 7 GA5的OSGI模块里,JournalArticleLocalServiceUtil确实拿不到你需要的articleDisplay内容。原因很简单:这个工具类负责的是获取原始的JournalArticle实体数据,而articleDisplay是经过FreeMarker模板渲染、合并了themeDisplay、serviceContext等上下文信息后的最终展示内容,得用专门的方法来生成。
下面是具体的实现步骤和代码示例:
1. 优先用OSGI服务注入,替代静态Util类
在Liferay 7的OSGI环境中,静态工具类(比如*Util)容易出现类加载器冲突或者服务无法正确获取的问题,官方推荐用**声明式服务(Declarative Services)**依赖注入所需的服务。
2. 调用getArticleDisplay方法获取渲染后的内容
JournalArticleLocalService提供了getArticleDisplay方法,专门用来生成经过模板渲染的Web内容展示字符串。你需要传入正确的上下文参数,和你FreeMarker模板里用到的上下文保持一致。
完整的Portlet代码示例
import com.liferay.journal.service.JournalArticleLocalService; import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.WebKeys; import javax.portlet.PortletException; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import java.io.IOException; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @Component( immediate = true, property = { "com.liferay.portlet.display-category=category.sample", "com.liferay.portlet.instanceable=true", "javax.portlet.display-name=Custom Journal Content Portlet", "javax.portlet.init-param.template-path=/", "javax.portlet.init-param.view-template=/view.jsp", "javax.portlet.resource-bundle=content.Language", "javax.portlet.security-role-ref=power-user,user" }, service = MVCPortlet.class ) public class CustomJournalPortlet extends MVCPortlet { @Reference private JournalArticleLocalService _journalArticleLocalService; @Override public void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { // 获取当前请求的ThemeDisplay(和你模板里的上下文一致) ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY); long groupId = themeDisplay.getScopeGroupId(); // Web内容所在的站点ID String articleId = "YOUR_WEB_CONTENT_ID"; // 替换成你的Web内容ID String languageId = themeDisplay.getLanguageId(); // 当前用户的语言ID try { // 获取Web内容的最新版本号(如果你需要指定版本,可以直接传数字,比如1.0) double latestVersion = _journalArticleLocalService.getLatestArticleVersion(groupId, articleId); // 生成渲染后的articleDisplay内容 String articleDisplay = _journalArticleLocalService.getArticleDisplay( groupId, articleId, latestVersion, languageId, themeDisplay, null ); // 将内容放到request中,供JSP渲染使用 renderRequest.setAttribute("articleDisplay", articleDisplay); } catch (Exception e) { e.printStackTrace(); // 这里可以添加异常处理逻辑,比如给用户返回错误提示 } super.doView(renderRequest, renderResponse); } }
对应的view.jsp渲染代码
在你的Portlet的view.jsp中,直接输出获取到的articleDisplay即可:
<%@ page contentType="text/html; charset=UTF-8" %> <div class="journal-content"> <%= request.getAttribute("articleDisplay") %> </div>
几个关键注意点
- 权限检查:确保当前用户有访问目标Web内容的权限,否则
getArticleDisplay可能返回空或者抛出权限异常。可以添加权限检查逻辑,比如用PermissionChecker验证用户权限。 - 参数正确性:
groupId必须是Web内容所在的站点ID,articleId要和你创建Web内容时的ID完全匹配,语言ID要对应Web内容已有的本地化版本。 - ServiceContext参数:
getArticleDisplay的最后一个参数是serviceContext,可以传null,方法内部会自动基于当前请求生成合适的serviceContext,和你模板里的上下文保持一致。
内容的提问来源于stack exchange,提问作者Alessandra
相关产品推荐
相关产品推荐

