JSP+Servlet+MVC实现JavaWeb分页

我是2018届毕业生。最近忙着做毕业设计,所以很久没有写东西记录自己的学习情况了。今天接触到了JavaWeb分页,刚开始没有头绪然后在网上看了一些博客,然后自己慢慢的实现了,这里总结一下心得体会,也为了以后方便查看。
写在前面:刚开始我看了几篇网络文章,有了一点点头绪,但是还是很模糊,当我开始动手做并结合网络经验贴慢慢的思路就出来了,越来越清晰。所以有时候生活就像行走的朦胧的大雾之中,我们要勇敢的踏出第一步,只有这样眼前的路才会更清晰。

一、效果

首先不管其他的我们先看看实现之后的效果:

页面效果

我们可以从该页面得出如下信息:pageSize(页面展示数据数量)、currentPage(当前页面)、startIndex(页面的第一条数据数据)、endIndex(页面最后一条数据)、页面选项卡只有五个可见start(第一个页面选项卡)、end(最后一个页面选项卡)、totalPage(总页数)、totalRecord(总记录数)如果你对这些信息有些不解,那就先不要管他。你就把这个页面当做一个对象,这个对象有这些属性。既然这个页面是个对象里面还有9个元素(上图的9视频)所以这个对象还有一个存放着九个视频的容器list。

二、思路

我们的工作就是1.从数据库查找到视频记录,然后后台的逻辑部分帮我们从这些记录中抽出我们想要的记录并且2.构造出一个上面提到的页面对象 3.将该对象传到jsp页面然后得到这个界面(当然我上面的思路不是唯一的而且频繁访问数据库,你可以先按我的思路走一走,然后再试试其他思路)

三、实现

也许现在你还是没有思路,或者很模糊。不要急,如果你只是在脑子里想,是没有结果的除非你写了很久的代码。打开你的电脑跟着走,慢慢的就有思路了。下面是我的项目目录结构:


项目目录结构
  • 首先:创建一个page类用来存放我们页面将要显示的数据(仔细读注释)
package com.learning.model;

import java.util.ArrayList;
import java.util.List;
//每一页的模型
public class Page {
    //已知数据
    private int currentPage;//当前页(通过前台获取)
    private int pageSize;//每页显示的数据条数(自己设定)
    private int totalRecord;//数据库查询结果条数
    private List list = new ArrayList();//存放当前要展示的数据的容器大小为pageSize
    
    //计算得出
    private int totalPage;//总页数totalRecord/pageSize;
    private int startIndex;//每页第一条数据的索引
    private int endIndex;//每页最后一条数据的索引
    private int start;//可点击页的开始页
    private int end;//可点击页的最后一个
    
    //在构造函数中计算出属性值
    public Page(int currentPage, int pageSize, int totalRecord){
        this.currentPage = currentPage;
        this.pageSize = pageSize;
        this.totalRecord = totalRecord;
        
        //求总页数
        if(totalRecord%pageSize == 0){//可以整除情况
            this.totalPage = totalRecord/pageSize;
        }else{//不能整除有余数
            this.totalPage = totalRecord/pageSize + 1;
        }
        
        //计算每页的开始数据和结束数据的索引(需要根据当前页来确定)
        this.startIndex = (currentPage-1) * pageSize;//每页的第一条数据
        if(currentPage == totalPage){//如果当前页是最后一页
            this.endIndex = totalRecord - 1;
        }else{//当前页不是最后一页
            this.endIndex = startIndex + pageSize - 1;
        }
        //选项卡的起始页和最后一页默认值为1-5
        this.start = 1;
        this.end = 5;
        if(totalPage <= 5){//总页数小于等于5
            this.end = totalPage;
        }else{//如果总页数大于5根据当前页数来计算start和end
            this.start = currentPage - 2;
            this.end = currentPage + 2;
            if(this.start <= 0){
                this.start = 1;
                this.end  = 5;
            }
            if(this.end > totalPage){
                this.end = totalPage;
                this.start = end - 4;
            }
        }
    }
    //下面是geter和seter方法
    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getPageSize() {
        return pageSize;
    }

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

    public int getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(int totalRecord) {
        this.totalRecord = totalRecord;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    public int getTotalPage() {
        return totalPage;
    }

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

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }
    public int getEndIndex() {
        return endIndex;
    }

    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }
    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }
    
}
  • 然后:在service层调用dao层连接数据库查找数据,然后构造我们需要的Page对象我将这两部写在service层的一个类里面了:
package com.learning.service;

import java.util.ArrayList;
import java.util.List;

import com.learning.dao.DB;
import com.learning.model.Page;
import com.learning.model.Video;

import java.sql.*;

public class PageService {
    //连接数据库查询数据
    public static List findAllVideos(){
        Connection conn = DB.getConn();
        Statement stmt = DB.getStmt(conn);
        String sql = "select * from videos";
        ResultSet rs = DB.executeQuery(stmt, sql);
        List videoList = new ArrayList();
        try {//将查询结果放进容器中
            while(rs.next()){
                Video v = new Video();
                v.init(rs);
                videoList.add(v);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{//关闭资源
            DB.close(rs);
            DB.close(stmt);
            DB.close(conn);
        }
        return videoList;
    }
    
    //构建Page模型
    public static Page construPage(int currentPage, int pageSize){
        //获取数据库查询结果集
        List videoList = new ArrayList();
        videoList = findAllVideos();
        
        //构建page模型
        int totalRecord = videoList.size();
        System.out.println("数据规模:"+totalRecord);//调试可忽略
        Page pg = new Page(currentPage,pageSize,totalRecord);//构建page对象
        List currentList = new ArrayList();//每页显现的那九条数据的容器
        int startIndex = pg.getStartIndex();//每一页的起始索引
        int endIndex = pg.getEndIndex();//每一页的终止索引
        System.out.println("起始数据索引:"+startIndex);//调试可忽略
        System.out.println("最后数据索引:"+endIndex);//调试可忽略
        /根据每页的起始数据和最后一条数据的索引选出那九条数据并复制到currentlist
        currentList.addAll(videoList.subList(startIndex, endIndex+1));
        System.out.println("展示数据规模:"+currentList.size());
        pg.setList(currentList);//将currentlist设置到page对象的容器
        return pg;
    }

    
}

//dao层代码不做解释

package com.learning.dao;

import java.sql.*;

public class DB {
    public static Connection getConn(){//获取数据库连接
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/learning?user=root&password=root");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
    
    public static Statement getStmt(Connection conn){//创建会话
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return stmt;
    }
    
    public static ResultSet executeQuery(Statement stmt, String sql){//返回查询结果
        ResultSet rs = null;
        
        try {
            rs = stmt.executeQuery(sql);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return rs;
    }
    
    public static int update(Statement stmt, String sql) {
        int state = 0;
        try {
            state = stmt.executeUpdate(sql);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return state;
        
    } 
    
    public static void close(Connection conn){
        if(conn != null){
            try {
                conn.close();
                conn = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    } 
    
    public static void close(Statement stmt){
        if(stmt != null){
            try {
                stmt.close();
                stmt = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void close(ResultSet rs){
        if(rs != null){
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
        }
    }
    
}
  • 我们实现了思路中提到的3步的前两步接下来是第三步:将该对象传到jsp页面。浏览器请求传来当前页面,自己设置页面显示数据的条数。然后调用service层代码返回page对象,将该对象放到request中然后再jsp页面获取。代码如下:
package com.learning.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.learning.model.Page;
import com.learning.service.PageService;

public class VideoPage extends HttpServlet {

    public VideoPage() {
        super();
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String strcurpage = request.getParameter("currentpage");//接收当前页面值
        int currentPage;//通常第一次请求currentpage值为空这时设置默认值为1
        if(strcurpage!=null) {
            currentPage = Integer.parseInt(strcurpage);
        }else{ 
                currentPage = 1;
        }
        int pageSize = 9;//页面大小
        Page viewPage = PageService.construPage(currentPage, pageSize);//获取请求页面对象
        
        request.setAttribute("viewpage", viewPage);//将页面对象放入request中
        request.getRequestDispatcher("./videodisplay.jsp").forward(request, response);//跳转到jsp页面
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

}

  • 最后是jsp页面的显示(只贴出关键部分):
    el标签对list里的九条数据的显示(css渣渣能看就好)
 <c:forEach items="${requestScope.viewpage.list}" var="video">
    <li class="nav-item" style="display:inline-block;width:320px;margin:23px">
        <video style="display:block"src="${video.loc}"  width="320px" height="240px" controls="controls"></video>
        <div style="display:inline-block"><a class="nav-link text-dark" href="./videoplay.jsp?id=${video.id}">${video.desc}</a></div>
    </li>
</c:forEach>

页面选项卡的显示(主要分清这四种情况):

     <ul class="pagination">
        <!-- 总页数大于1如果当前页为第一页 上一页无效下一页有效-->
        <c:if test="${requestScope.viewpage.totalPage > 1 && requestScope.viewpage.currentPage == 1}">
            <li class="page-item"><a class="page-link" href="" onclick="return false" data-toggle="popover1" data-content="没有了">上一页</a></li>
            <c:forEach var="i" begin="${requestScope.viewpage.start}" end="${requestScope.viewpage.end}" step="1">
                <c:if test="${requestScope.viewpage.currentPage == i}"><li class="page-item active"><a class="page-link" href="">${i}</a></li></c:if>
                <c:if test="${requestScope.viewpage.currentPage != i}"><li class="page-item"><a class="page-link" href="./VideoPage?currentpage=${i}">${i}</a></li></c:if>
            </c:forEach>
            <li class="page-item"><a class="page-link" href="./VideoPage?currentpage=${requestScope.viewpage.currentPage+1}">下一页</a></li>
        </c:if>
        <!-- 如果当前页不是第一页也不是最后一页,上一页和下一页都有效 -->
        <c:if test="${requestScope.viewpage.currentPage > 1 && requestScope.viewpage.currentPage < requestScope.viewpage.totalPage}">
            <li class="page-item"><a class="page-link" href="./VideoPage?currentpage=${requestScope.viewpage.currentPage-1}">上一页</a></li>
            <c:forEach var="i" begin="${requestScope.viewpage.start}" end="${requestScope.viewpage.end}" step="1">
                <c:if test="${requestScope.viewpage.currentPage == i}"><li class="page-item active"><a class="page-link" href="">${i}</a></li></c:if>
                <c:if test="${requestScope.viewpage.currentPage != i}"><li class="page-item"><a class="page-link" href="./VideoPage?currentpage=${i}">${i}</a></li></c:if>
            </c:forEach>
            <li class="page-item"><a class="page-link" href="./VideoPage?currentpage=${requestScope.viewpage.currentPage+1}">下一页</a></li>
        </c:if>
        <!-- 总页数大于1 如果当前页为最后一页 下一页无效-->
        <c:if test="${requestScope.viewpage.totalPage > 1 && requestScope.viewpage.currentPage == requestScope.viewpage.totalPage}">
            <li class="page-item"><a class="page-link" href="./VideoPage?currentpage=${requestScope.viewpage.currentPage-1}">上一页</a></li>
            <c:forEach var="i" begin="${requestScope.viewpage.start}" end="${requestScope.viewpage.end}" step="1">
                <c:if test="${requestScope.viewpage.currentPage == i}"><li class="page-item active"><a class="page-link" href="">${i}</a></li></c:if>
                <c:if test="${requestScope.viewpage.currentPage != i}"><li class="page-item"><a class="page-link" href="./VideoPage?currentpage=${i}">${i}</a></li></c:if>
            </c:forEach>
            <li class="page-item"><a class="page-link" href="#" onclick="return false" data-toggle="popover1" data-content="没有了">下一页</a></li>
        </c:if> 
        <!-- 总页数==1 -->
        <c:if test="${requestScope.viewpage.totalPage == 1}">
            <li class="page-item"><a class="page-link" href="#" onclick="return false" data-toggle="popover1" data-content="没有了">上一页</a></li>
            <li class="page-item active"><a class="page-link" href="">1</a></li>
            <li class="page-item"><a class="page-link" href="#" onclick="return false" data-toggle="popover1" data-content="没有了">下一页</a></li>
        </c:if> 
    </ul>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容