前几天试了试JFinal框架,感觉用起来还是蛮方便的,作者似乎借鉴了一些Ruby的思想,并且集成了一些常用的功能类,比如分页,图片验证码等等。个人觉得,与其说这是一个java的开发框架,不如说它是一个简洁的建站解决方案。

JFinal的分页类感觉还是很方便的,官方的示例很简单也很清楚,直接调Model的paginate方法,传入当前页码,每页显示数量等参数就行了。不过,这只是分页查询数据库得到的数据列表,除此以外,还得把分页的信息展示在前端页面上,这时候就得自己实现一些分页逻辑以及相应的前端了。

所以,我就简单封装了一个分页类,把一些分页需要的页面元素计算封装进去,配合freemarker,实现了一个功能还算完全的分页扩展,其实也不能叫扩展,只是一种简单的实现方式,贴出来给大家参考参考。

先贴个效果图:

jfinal-pageHander.png

PageHandler 类:

package com.eric.huahuajia.dto;

import com.jfinal.plugin.activerecord.Page;

public class PageHandler {

    // 当前页码
    public int pageNumber;
    // 每页数量
    public int pageSize;
    // 总页数
    public int totalPage;
    // 总行数
    public int totalRow;
    // 是否有下一页
    public boolean hasNextPage; 
    // 是否有前一页
    public boolean hasPreviousPage; 
        // 下一页页码
    public int nextPageNumber; 
     // 前一页页码
    public int previousPageNumber; 
    
    
    // 页面基础URL,用作翻页事件
    public String basePathUrl;
    // 偏移量,当分页过多时只显示当前页前后偏移部分页码
    public int offSetNum = 3;
    // 需要显示出来的页码范围 - 起始页码
    public int startPageNum;
    // 需要显示出来的页码范围 - 结束页码
    public int endPageNum;
    
    /**
     * 构造函数,初始化
     * @param pageNumber
     * @param pageSize
     * @param totalPage
     * @param totalRow
     */
    public PageHandler(int pageNumber,int pageSize,int totalPage,int totalRow) {
        this.pageNumber = pageNumber;
        this.pageSize = pageSize;
        this.totalPage = totalPage;
        this.totalRow = totalRow;
        this.calculatePage();
        this.calculateShowPage();
    }

    /**
     * 构造函数,根据JFinal内置Page初始化
     * @param pageInfo
     */
    public <T> PageHandler(Page<T> pageInfo){
        this.pageNumber = pageInfo.getPageNumber();
        this.pageSize = pageInfo.getPageSize();
        this.totalPage = pageInfo.getTotalPage();
        this.totalRow = pageInfo.getTotalRow();
        this.calculatePage();
        this.calculateShowPage();
    }
    /**
     * 计算当前页是否有前后页,并得出前后页码
     */
    private void calculatePage() {
        if ((this.pageNumber - 1) > 0) {
            this.hasPreviousPage = true;
            this.previousPageNumber = this.pageNumber - 1;
        } else {
            this.hasPreviousPage = false;
            this.previousPageNumber = 0;
        }

        if (this.pageNumber >= this.totalPage) {
            this.hasNextPage = false;
            this.nextPageNumber = 0;
        } else {
            this.hasNextPage = true;
            this.nextPageNumber = this.pageNumber + 1;
        }

    }
    /**
     * 计算需要显示出来的页码范围
     */
    private void calculateShowPage(){
        // 前偏移
        int preCalulateNum = this.pageNumber - this.offSetNum;
        // 后偏移
        int nextCalulateNum = this.pageNumber + this.offSetNum;
        
        if (preCalulateNum > 0){
            this.startPageNum = preCalulateNum;
        }else{
            this.startPageNum = 1;
        }
        
        if (nextCalulateNum > this.totalPage){
            this.endPageNum = this.totalPage;
        }else{
            this.endPageNum = nextCalulateNum;
        }
    }
    
    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getTotalRow() {
        return totalRow;
    }

    public void setTotalRow(int totalRow) {
        this.totalRow = totalRow;
    }

    public boolean isHasNextPage() {
        return hasNextPage;
    }

    public void setHasNextPage(boolean hasNextPage) {
        this.hasNextPage = hasNextPage;
    }

    public boolean isHasPreviousPage() {
        return hasPreviousPage;
    }

    public void setHasPreviousPage(boolean hasPreviousPage) {
        this.hasPreviousPage = hasPreviousPage;
    }

    public int getNextPageNumber() {
        return nextPageNumber;
    }

    public void setNextPageNumber(int nextPageNumber) {
        this.nextPageNumber = nextPageNumber;
    }

    public int getPreviousPageNumber() {
        return previousPageNumber;
    }

    public void setPreviousPageNumber(int previousPageNumber) {
        this.previousPageNumber = previousPageNumber;
    }

    public String getBasePathUrl() {
        return basePathUrl;
    }

    public void setBasePathUrl(String basePathUrl) {
        this.basePathUrl = basePathUrl;
    }

    public int getOffSetNum() {
        return offSetNum;
    }

    public void setOffSetNum(int offSetNum) {
        this.offSetNum = offSetNum;
    }

    public int getStartPageNum() {
        return startPageNum;
    }

    public void setStartPageNum(int startPageNum) {
        this.startPageNum = startPageNum;
    }

    public int getEndPageNum() {
        return endPageNum;
    }

    public void setEndPageNum(int endPageNum) {
        this.endPageNum = endPageNum;
    }
    
    
}

这个类就是定义了一些分页的元素,通过JFinal分页方法返回的值,简单计算封装了一下

然后,与此配合的freemarker页面:

<#if pageHandler??>
<div class="row">    
    <div class="col-xs-6">
         <div class="box-footer clearfix" id="">共 ${pageHandler.totalRow} 条;${pageHandler.totalPage} 页;当前第 ${pageHandler.pageNumber} 页</div>
    </div>
    <div class="col-xs-6">
        <div class="box-footer clearfix">
            <ul class="pagination no-margin pull-right">
            <#if pageHandler.hasPreviousPage>
                <li class="prev"><a href="${ctx}${pageHandler.basePathUrl}${pageHandler.previousPageNumber}">← 上一页</a></li>
            <#else>
                <li class="prev disabled"><a>← 上一页</a></li>
            </#if>
                <#-- 起始展示页跟首页相比大于0 -->
                <#if (pageHandler.startPageNum - 1 > 0)>
                    <li><a>...</a></li>
                </#if>
                <#list (pageHandler.startPageNum)..(pageHandler.endPageNum) as pNum> 
                    <#if pNum == pageHandler.pageNumber>
                        <li class="active"><a>${pNum}</a></li>
                    <#else>
                        <li><a href="${ctx}${pageHandler.basePathUrl}${pNum}">${pNum}</a></li>
                    </#if>                
                </#list>
                <#-- 尾页跟结束展示页相比大于0 -->
                <#if (pageHandler.totalPage - pageHandler.endPageNum > 0)>
                    <li><a>...</a></li>
                </#if> 
            <#if pageHandler.hasNextPage>
                <li class="next"><a href="${ctx}${pageHandler.basePathUrl}${pageHandler.nextPageNumber}">下一页 →</a></li>
            <#else>
                <li class="next disabled"><a>下一页 →</a></li>
            </#if>
            </ul>
        </div>
    </div>
</div>
</#if>

使用也很简单:

// 调JFinal原生分页方法,获取返回值
Page<WikiArticle> wikiListPage = wikiService.queryPagedWikiList(pageNumber, HuaConstants.ONEPAGE_SIZE_NUM);
// 将原生分页类返回值做为参数传入封装的分页类,得到封装好的分页信息
PageHandler pageHandler = new PageHandler(wikiListPage);
pageHandler.setBasePathUrl("/dashboard/wikiList/");

OK,很简单,但是个人觉得还是蛮实用的。