先看下最終效果:
源碼地址:https://github.com/zhouyu629/freemarker-page-demo
實現過程
一、新建springboot項目,導入相關依賴包
<!--web組件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--lombok簡化實體類的get set方法--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- freemarker--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
配置文件,設置freemarker相關參數
spring: application: name: demo freemarker: allow-request-override: true cache: false check-template-location: true charset: UTF-8 content-type: text/html; charset=utf-8 expose-request-attributes: false expose-session-attributes: false expose-spring-macro-helpers: false suffix: .ftl template-loader-path: classpath:/templates settings: number_format: 0 # freemarker會自動將整型數字轉換為千位分隔,不方便 http: encoding: charset: utf-8 force: true server: port: 8088
二、創建自定義分頁類
構造方法里,將頁碼、分頁大小等傳進去,自動計算總頁數。
package com.demo.util; import lombok.Data; import java.util.List; /** * @program: zyproject * @description: 分頁通用實體類 * @author: zhouyu(zhouyu629 # qq.com) * @create: 2020-02-16 **/ @Data public class MyPager<T> { private int page; //當前頁碼,從1開始 private int pagesize; //分頁大小 private int totalpages; //總頁數 private int totalrecords; //總記錄數 private List<T> list; //構造函數中計算總頁數 public MyPager(int page, int pagesize, int totalrecords, List<T> list){ this.page = page; this.pagesize = pagesize; this.totalrecords = totalrecords; this.list = list; //計算總頁數 this.totalpages = totalrecords/pagesize; if(totalrecords%pagesize!=0){ this.totalpages = this.totalpages + 1; }; } }
順便再創建一個實體類供測試,直觀一點,用hasmap也行。
package com.demo.util; import lombok.Data; /** * @program: freemarker-page-demo * @description: 用戶實體 * @author: zhouyu(zhouyu629 # qq.com) * @create: 2020-03-07 **/ @Data public class UserEntity { private Integer user_id; private String user_name; private Integer age; private String login_name; private String mail; }
三、Controller返回分頁數據
實際應用中,pagesize可以寫到配置文件或數據庫中,允許全局變更。
數據源list也應該從數據層獲取。
package com.demo.controller; import com.demo.util.MyPager; import com.demo.util.UserEntity; import com.sun.org.apache.xpath.internal.operations.Mod; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @program: freemarker-page-demo * @description: demo首頁 * @author: zhouyu(zhouyu629 # qq.com) * @create: 2020-03-06 **/ @Controller public class IndexController { @RequestMapping("/index.html") public String index(@RequestParam(name = "page",defaultValue = "1") Integer page, @RequestParam(name = "pagesize",defaultValue = "10") Integer pagesize, Map<String,Object> map){ //造一些分頁數據 List<UserEntity> list = new ArrayList<>(); for(int i = ((page-1)*pagesize+1);i<((page-1)*pagesize+pagesize);i++){ UserEntity userEntity = new UserEntity(); userEntity.setAge(20); userEntity.setLogin_name("user"+i); userEntity.setMail("user"+i+"@gmail.com"); userEntity.setUser_id(i); userEntity.setUser_name("user"+i); list.add(userEntity); } MyPager myPager = new MyPager(page,pagesize,500,list); map.put("users",myPager); return "/index"; } }
四、自定義freemarker分頁宏
<#-- 參數解釋: page:當前頁碼,從1開始 pagesize:分頁大小 totalpages:總頁數。也可以放到模板里計算。這里在MyPager類里已計算過了。 totalrecords:總記錄數 url:鏈接地址,自動拼接page參數。為了簡單,沒有判斷當前頁面是否有get參數了,直接做了&連接,默認認為原來就有參數。當前你也可以用servlet自己獲取當前url及參數,就不用傳了。 以上這些參數除url外均可以從MyPager實例中獲取。其實可以直接把mypager實例傳進來,為了便於以后擴展,分字段傳過來。 --> <#macro fpage page pagesize totalpages totalrecords url> <li class="page-item"><span class="page-link">共條${totalrecords}記錄 第${page}頁/共${totalpages}頁</span></li> <#--startpage:起始頁碼就是page,endpage:結束頁碼,showfirstpage是否顯示首頁按鈕,showlastpage:是否顯示末頁按鈕,showpre是否顯示前...,shownext是否顯示后...--> <#assign startpage = page,endpage=10,showfirstpage=false,showlastpage=false,showpre=false,shownext=false,prepage = 1,nextpage=11> <#--是否顯示首頁按鈕及計算初始頁碼--> <#if page gt 1> <#assign showfirstpage = true> <#--startpage向前挪4頁,如果不足4頁,則startpage=1--> <#assign startpage=(page-4)> <#if startpage lte 0> <#assign startpage = 1> </#if> </#if> <#--是否顯示前n頁的...,以及...的鏈接--> <#if page gt 5> <#assign showpre = true,prepage=page-5> </#if> <#--計算endpage--> <#if page+pagesize-1 lt totalpages> <#assign endpage = page+pagesize-1> <#--顯示后面的...按鈕--> <#assign shownext = true> <#--后面...的頁面碼--> <#assign nextpage=page+pagesize> <#--顯示末頁--> <#assign showlastpage = true> <#else> <#assign endpage = totalpages> </#if> <#if endpage lte 0> <#assign endpage = 1> </#if> <#--開始展示--> <#--首頁--> <#if showfirstpage> <li class="page-item"><span><a class="page-link" href="${url}&page=1">首頁</a></span></li> </#if> <#--前面的...--> <#if showpre> <li class="page-item"><span><a class="page-link" href="${url}&page=${prepage}">...</a></span></li> </#if> <#--顯示的頁碼按鈕--> <#list startpage..endpage as p> <li class="page-item <#if p == page>active</#if>"><span><a class="page-link" href="${url}&page=${p}">${p}</a></span></li> </#list> <#--后面的...--> <#if shownext> <li class="page-item"><span><a class="page-link" href="${url}&page=${nextpage}">...</a></span></li> </#if> <#--顯示尾頁--> <#if showlastpage> <li class="page-item"><span><a class="page-link" href="${url}&page=${totalpages}">末頁</a></span></li> </#if> </#macro>
五、html頁面引用分頁
核心是這一段,根據后台傳過來的MyPager實例users,調用freemarker宏,傳遞相關參數:
<#import "./public/page.ftl" as fpage /> <@fpage.fpage page=users.page pagesize=users.pagesize totalpages=users.totalpages totalrecords=users.totalrecords url="index.html?key=" />
完整html代碼
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <title>Hello, world!</title> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-sm"> <table class="table"> <thead class="thead-dark"> <tr> <th scope="col">id</th> <th scope="col">登錄名</th> <th scope="col">姓名</th> <th scope="col">mail</th> <th scope="col">年齡</th> </tr> </thead> <tbody> <#list users.list as list> <tr> <th scope="row">${list.user_id}</th> <td>${list.login_name}</td> <td>${list.user_name}</td> <td>${list.mail}</td> <td>${list.age}</td> </tr> </#list> </tbody> </table> <!--pager--> <nav aria-label="Page navigation example"> <ul class="pagination"> <#import "./public/page.ftl" as fpage /> <@fpage.fpage page=users.page pagesize=users.pagesize totalpages=users.totalpages totalrecords=users.totalrecords url="index.html?key=" /> </ul> </nav> </div> </div> . </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> </body> </html>
打完收功!