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

如何配置Freemarker实现带搜索参数的分页功能?

如何实现带搜索参数的Freemarker分页功能?

我刚好遇到过类似的问题,结合你提供的尝试过程,下面是正确配置带搜索参数的Freemarker分页功能的完整步骤,能彻底解决分页时搜索参数丢失的问题:

1. 后端Controller:传递包含搜索参数的完整URL

首先要在Controller层处理分页请求时,把当前的搜索参数(比如filter)整合到传递给模板的url变量中,而不是只传递基础路径。这样前端模板不需要自己判断是否存在搜索参数,直接基于这个完整URL拼接分页参数即可。

示例代码:

Page<MessageDto> page = messageService.messageList(pageable, filter, user);
// 根据是否存在搜索参数,构建完整的基础URL
if (StringUtils.isNotBlank(filter)) {
    model.addAttribute("url", String.format("/main?filter=%s", filter));
} else {
    model.addAttribute("url", "/main");
}
model.addAttribute("page", page);
model.addAttribute("filter", filter); // 回显搜索框内容
return "main";

为什么要这么做?
这一步的核心是把当前请求的搜索状态固化到url变量里,避免前端模板去做复杂的参数判断和拼接,同时保证后续分页请求能携带当前的搜索参数。

2. 修改Freemarker分页宏的URL拼接逻辑

接下来要修改分页宏中分页链接和每页条数切换链接的拼接逻辑,通用判断URL是否已有查询参数(通过是否包含?),来决定用&还是?拼接新参数,而不是针对filter做硬编码判断。

修改后的分页宏关键代码:

<!-- 分页页码链接 -->
<li class="page-item">
    <a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${p - 1}&size=${page.getSize()}" tabindex="-1">
        ${p}
    </a>
</li>

<!-- 每页条数切换链接 -->
<li class="page-item">
    <a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${page.getNumber()}&size=${c}" tabindex="-1">
        ${c}
    </a>
</li>

为什么之前的方案失效?

  • 第一种硬判断URL是否包含filter的方式:扩展性极差,如果以后新增其他查询参数(比如status、dateRange),这个判断就会失效,导致参数丢失。
  • 第二种仅前端用url?contains('?')的方式:如果后端传递的url是不带搜索参数的基础路径(比如/main),那前端拼接后自然会丢失filter参数,所以必须由后端传递包含当前搜索参数的完整URL。

完整的分页宏参考

调整后的完整分页宏代码:

<#macro pager url page>
<#if page.getTotalPages() gt 7>
<#assign totalPages = page.getTotalPages() pageNumber = page.getNumber() + 1 head = (pageNumber > 4)?then([1, -1], [1, 2, 3]) tail = (pageNumber < totalPages - 3)?then([-1, totalPages], [totalPages - 2, totalPages - 1, totalPages]) bodyBefore = (pageNumber > 4 && pageNumber < totalPages - 1)?then([pageNumber - 2, pageNumber - 1], []) bodyAfter = (pageNumber > 2 && pageNumber < totalPages - 3)?then([pageNumber + 1, pageNumber + 2], []) body = head + bodyBefore + (pageNumber > 3 && pageNumber < totalPages - 2)?then([pageNumber], []) + bodyAfter + tail >
<#else>
<#assign body = 1..page.getTotalPages()>
</#if>
<div class="container-fluid mt-3">
<div class="row">
<ul class="pagination col">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Pages</a>
</li>
<#list body as p>
<#if (p - 1) == page.getNumber()>
<li class="page-item active">
<a class="page-link" href="#" tabindex="-1">${p}</a>
</li>
<#elseif p == -1>
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">...</a>
</li>
<#else>
<li class="page-item">
<a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${p - 1}&size=${page.getSize()}" tabindex="-1">
${p}
</a>
</li>
</#if>
</#list>
</ul>
<ul class="pagination col justify-content-end">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Elements per page</a>
</li>
<#list [20, 40, 80, 120] as c>
<#if c == page.getSize()>
<li class="page-item active">
<a class="page-link" href="#" tabindex="-1">${c}</a>
</li>
<#else>
<li class="page-item">
<a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${page.getNumber()}&size=${c}" tabindex="-1">
${c}
</a>
</li>
</#if>
</#list>
</ul>
</div>
</div>
</#macro>

这样配置后,无论是无搜索参数的基础分页,还是带filter的搜索后分页,都能正确携带参数,不会出现跳转后搜索参数丢失的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:49:05