You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Liferay 7中重写SearchDisplayContext类并添加自定义方法

在Liferay 7 DXP中为portal-search-web的SearchDisplayContext添加自定义方法的解决方案

直接修改Liferay自带的SearchDisplayContext类肯定不可行——一来内部包的类不允许直接修改,二来升级Liferay时你的修改会被覆盖。我们可以通过OSGi组件替换/继承的方式来扩展这个类,下面是具体步骤:

1. 准备自定义模块

首先创建一个Liferay OSGi模块,在模块的构建配置中添加对portal-search-web的依赖:

  • 如果用Gradle,在build.gradle中加入:
    dependencies {
        compileOnly group: "com.liferay", name: "com.liferay.portal.search.web", version: "对应你的Liferay版本号"
    }
    
  • 在bnd.bnd中确保导入所需的内部包:
    Import-Package: com.liferay.portal.search.web.internal.display.context,*
    

2. 创建自定义的SearchDisplayContext类

我们通过继承原类并注册为更高优先级的OSGi组件,来替换原有类。这样既可以重用原有逻辑,又能添加自定义方法:

import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.search.web.internal.display.context.SearchDisplayContext;
import com.liferay.portal.search.web.portlet.preferences.SearchPortletPreferences;
import com.liferay.portal.search.web.search.request.SearchRequestBuilder;
import com.liferay.portal.search.web.search.response.SearchResponse;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import org.osgi.service.component.annotations.Component;

@Component(
    immediate = true,
    property = {
        "request.scoped=true",
        "service.ranking:Integer=100" // 设置更高优先级,确保优先加载我们的类
    },
    service = SearchDisplayContext.class
)
public class CustomSearchDisplayContext extends SearchDisplayContext {

    // 注入父类构造函数所需的所有依赖
    @Inject
    public CustomSearchDisplayContext(
        com.liferay.portal.kernel.portlet.Portal portal,
        ThemeDisplay themeDisplay,
        HttpServletRequest httpServletRequest,
        SearchPortletPreferences searchPortletPreferences,
        SearchRequestBuilder searchRequestBuilder,
        SearchResponse searchResponse,
        WebKeys webKeys) {
        super(portal, themeDisplay, httpServletRequest, searchPortletPreferences, searchRequestBuilder, searchResponse, webKeys);
    }

    // 这里添加你的自定义方法
    public String getCustomSearchSummary() {
        // 可以直接调用父类的方法获取原有数据,比如搜索结果总数
        long totalHits = getSearchResponse().getTotalHits();
        return String.format("本次搜索共找到 %d 条结果", totalHits);
    }

    // 如果你需要修改原有方法的逻辑,也可以重写父类方法
    @Override
    public boolean isShowEmptyResultsMessage() {
        // 比如自定义空结果时的显示逻辑
        return super.isShowEmptyResultsMessage();
    }
}

3. 部署并测试

  • 将模块打包成JAR文件,部署到Liferay的osgi/modules目录下,Liferay会自动加载这个新的组件。
  • 在搜索页面的JSP(比如search_results.jsp)中调用自定义方法:
    <%
    CustomSearchDisplayContext searchDisplayContext = (CustomSearchDisplayContext)request.getAttribute(SearchDisplayContext.class.getName());
    %>
    <div class="custom-search-summary">
        <%= searchDisplayContext.getCustomSearchSummary() %>
    </div>
    

注意事项

  • 由于原类属于internal包,Liferay升级时可能会修改其构造函数或方法签名,升级后需要检查并同步你的自定义类。
  • 如果你不想继承原类,也可以使用OSGi装饰器模式包装原有组件,但这种方式需要实现原类的所有方法,相对繁琐,适合不需要重用大量原有逻辑的场景。

内容的提问来源于stack exchange,提问作者Pankaj Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:59:02