如何配置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
相关产品推荐
相关产品推荐

