java web 分页详解1

简介:

Java Web中如何更好地分页呢?

并且分页时要记住当时的查询条件(现场恢复)

我以一个案例来详细说明.

我做了一个订单查询,界面如下:

 这个订单查询有6个条件,而且有分页,每页显示10条记录.

查询页面(list.jsp)代码如下:

Java代码   收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
  4. <%  
  5.     String path = request.getContextPath();  
  6.     String basePath = request.getScheme() + "://"  
  7.             + request.getServerName() + ":" + request.getServerPort()  
  8.             + path + "/";  
  9. %>     
  10. <html xmlns="http://www.w3.org/1999/xhtml">  
  11. <head>  
  12. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  13. <title>个人信息管理</title>  
  14. <link rel="stylesheet" type="text/css" href="<%=path%>/static/css/tongy_xx.css">  
  15. <link rel="stylesheet" type="text/css" href="<%=path%>/static/css/ddcx.css">  
  16. <script type="text/javascript" src="<%=path%>/static/js/common_util.js"></script>  
  17.     <script type="text/javascript" src="<%=path%>/static/js/jquery-1.10.1.js"></script>  
  18.     <script type="text/javascript" src="<%=path%>/static/js/jquery.form.js"></script>  
  19.     <script type="text/javascript" src="<%=path%>/static/js/page.js"></script>  
  20.       
  21.   
  22.       
  23.     <jsp:include page="/WEB-INF/jsp/orders/orders.jsp"/>  
  24. </head>  
  25. <body>  
  26.       
  27.     <div class="box">  
  28.       
  29.         <jsp:include page="../public/top.jsp"/>  
  30.           
  31.         <jsp:include page="../public/left.jsp"/>  
  32.           
  33.         <form id="form" method="POST"  action="<%=path%>/orders/list"   >  
  34.         <div class="r_lr">  
  35.   
  36.               
  37.   
  38.                 <ul>  
  39.   
  40.                     <h3>订单查询</h3>  
  41.   
  42.                     <h4>检索条件</h4>  
  43.                       <Li>                      
  44.                         <label>条码/订单号:</label><input type="text" id="barCode" name="barCode" value="${view.barCode }" />  
  45.                     </Li>  
  46.                     <Li>  
  47.                             <label>订单类别:</label>  
  48.                             <select  id="orderclass" name="orderclass"  value="${view.orderclass }" >  
  49.                             <c:forEach items="${orderclass_map }" var="item" >  
  50.                               <option value="${item.key }" >   ${item.value }</option>    
  51.                             </c:forEach>  
  52.                             </select>  
  53.                     </Li>  
  54.                     <Li>  
  55.                             <label>医院/诊所:</label><input type="text" id="hospital" name="hospital" value="${view.hospital }" />  
  56.                     </Li>  
  57.                       
  58.                                 <Li>                      
  59.                         <label>医生:</label><input type="text" id="doctor" name="doctor" value="${view.doctor }" />  
  60.                     </Li>  
  61.                     <Li>  
  62.                             <label>患者:</label><input type="text" id="patient" name="patient" value="${view.patient }" />  
  63.                     </Li>  
  64.                     <Li>  
  65.                             <label>登记人:</label><input type="text" id="regname" name="regname" value="${view.regname }" />  
  66.                     </Li>  
  67.                       
  68.                       
  69.                     <Li class="submit"><input type="submit" value="查询" onclick="orders.checkForm()" /></Li>  
  70.   
  71.   
  72.   
  73.                 </ul>  
  74.   
  75.               
  76.             <h3>订单列表</h3>  
  77.               
  78.             <table style="color: white" >  
  79.                   
  80.                 <tr><th style="width:3">序号</th>  
  81.                 <th>条码</th><th>类别</th>  
  82.                 <th style="width:120" >医院/诊所</th>  
  83.                 <th>医生</th><th>患者</th>  
  84.                 <th style="display:none" >联系方式</th>  
  85.                 <th  >登记人</th>  
  86.                 <th style="width:100" >到厂日期</th>  
  87.                 <th style="width:120">操作</th></tr>  
  88.               
  89.                <c:forEach var="orders" items="${view.recordList}" varStatus="status">  
  90.                 <tr style="color:'red'" >  
  91.                     <td>${status.count }</td>  
  92.                     <td>${orders.barCode }</td>  
  93.                     <td>${orders.orderclass }</td>  
  94.                       
  95.                     <td>${orders.hospital }</td>  
  96.                       
  97.                     <td>${orders.doctor }</td>  
  98.                     <td>${orders.patient }</td>  
  99.                     <td style="display:none">${orders.tel }</td>  
  100.                     <td>${orders.regname }</td>  
  101.                     <td>${orders.inDate }</td>  
  102.                     <td>  
  103.                      <a  
  104.                         href="<%=path%>/orders/detail?barCode=${orders.barCode }&fsdf=${currentTime}">详情</a>  
  105.                         |<a  
  106.                         href="<%=path%>/osType/editInput?id=${orders.barCode }&fsdf=${currentTime}">防伪码</a>  
  107.                     </td>  
  108.                 </tr>  
  109.             </c:forEach>  
  110.                   
  111.                   
  112.                   
  113.             </table>  
  114.         <jsp:include page="../pageBottom.jsp">  
  115.             <jsp:param name="action" value="orders.query" />  
  116.         </jsp:include>  
  117.           
  118.           
  119.         </div>  
  120.         </form>  
  121.         </div>  
  122.       
  123.       
  124. </body>  
  125. </html>  

 我使用的是spring MVC框架,拿其中一个查询项来说,比如

<input type="text" id="doctor" name="doctor" value="${view.doctor }" />这是查询医生的.

后台控制器是如何接受查询的参数的呢?

后台controller 的action代码如下:

Java代码   收藏代码
  1. @RequestMapping(value = "/list")  
  2.     public String list(Model model,ToothOrders toothOrders, OrdersView view) {  
  3.         String barCode=toothOrders.getBarCode();  
  4.         ToothOrders toothOrders2=null;  
  5.         try {  
  6.             toothOrders2=toothOrders.clone();  
  7.             BeanUtils.copyProperties(view, toothOrders2);  
  8.         } catch (CloneNotSupportedException e) {  
  9.             e.printStackTrace();  
  10.         } catch (IllegalAccessException e) {  
  11.             e.printStackTrace();  
  12.         } catch (InvocationTargetException e) {  
  13.             e.printStackTrace();  
  14.         }  
  15.         if(ValueWidget.isNullOrEmpty(barCode)){  
  16.             PageAssistant.paging(toothOrders,true,view, toothOrdersDao);  
  17.         }else{  
  18.             PageAssistant.paging("barCode",barCode,view, toothOrdersDao);  
  19.         }  
  20.         int size=view.getRecordList().size();  
  21.         for(int i=0;i<size;i++){  
  22.             ToothOrders toothOrders3=null;  
  23.             toothOrders3=(ToothOrders)view.getRecordList().get(i);  
  24.             toothOrders3.setOrderclass(DictionaryParam.get("orderclass", toothOrders3.getOrderclass()));  
  25.         }  
  26.           
  27.         model.addAttribute("orderclass_map", DictionaryParam.get(Constant2.DICTIONARY_GROUP_ORDERCLASS));  
  28.         model.addAttribute("orders", toothOrders2);  
  29.         model.addAttribute("view", view);  
  30.         model.addAttribute("currentTime", TimeHWUtil.getCurrentTimestamp()  
  31.                 .getTime());  
  32.         return "orders/list";  
  33.     }  

 spring MVC 会自动把请求要素doctor 注入到action 方法list() 的参数ToothOrders toothOrders中,即toothOrders 中将会包含所有的请求要素(查询项).下面是查询时执行到controller 的list方法时的状态:

 

接受到请求要素之后,连接数据库进行查询操作.

我们发现list方法还有一个形参,OrdersView view,view是用于接收分页的信息(当前是第多少页,共有多少页,每页显示多少条记录)的.

查询之后,重新设置view 中的分页信息,然后返回给视图(页面)

 是如何把分页信息返回给页面的呢?

controller 的代码:

Java代码   收藏代码
  1. model.addAttribute("view", view);  

 页面pageBottom.jsp

 该页面是所有分页页面需要include进去的,是一个公共的页面

Java代码   收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
  4. <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>  
  5. <table style="height: 35px"  >  
  6.     <tr>  
  7.         <td nowrap="nowrap" style="width: 6%">  
  8.         <td nowrap="nowrap" style="width: 43%"><span style="color: white" >共  
  9.                   
  10.                 <c:choose>  
  11.           
  12.                     <c:when test="${view.totalRecords==0}"><font color="#df625c">0</font> </c:when>  
  13.                     <c:otherwise>  
  14.                         ${view.totalRecords }  
  15.                     </c:otherwise>  
  16.                 </c:choose>  
  17.                 条记录, 当前第<font color="#46bbfe"> <c:choose>  
  18.                     <c:when test="${view.totalPages==0 }">0</c:when>  
  19.                     <c:otherwise>  
  20.                     ${view.currentPage}  
  21.                 </c:otherwise>  
  22.                 </c:choose></font> / ${view.totalPages}页  
  23.         </span></td>  
  24.   
  25.   
  26.         <td nowrap="nowrap" style="display: none">  
  27.         <!-- 首页,view.currentPage的值为1 -->  
  28.         <td colspan="9"><span> <c:choose>  
  29.           
  30.                     <c:when test="${view.currentPage<=1}">首页</c:when>  
  31.                     <c:otherwise>  
  32.                         <a href="javascript:toPageFirst(${param.action})">首页</a>  
  33.                     </c:otherwise>  
  34.                 </c:choose> <c:choose>  
  35.                     <c:when test="${view.currentPage<=1}">上一页</c:when>  
  36.                     <c:otherwise>  
  37.                         <a href="javascript:toPagePre(${param.action})">上一页</a>  
  38.                     </c:otherwise>  
  39.                 </c:choose> <c:choose>  
  40.                     <c:when test="${view.currentPage>=view.totalPages }">下一页</c:when>  
  41.                     <c:otherwise>  
  42.                         <a href="javascript:toPageNext(${param.action})">下一页</a>  
  43.                     </c:otherwise>  
  44.                 </c:choose> <c:choose>  
  45.                     <c:when test="${view.currentPage>=view.totalPages}">尾页</c:when>  
  46.                     <c:otherwise>  
  47.                         <a href="javascript:toPageLast(${param.action})">尾页</a>  
  48.                     </c:otherwise>  
  49.                 </c:choose> <strong>转</strong> <c:choose>  
  50.                     <c:when test="${view.totalPages==0 }">  
  51.                         <input type="text" id="view.currentPage" name="currentPage" value="0" />  
  52.                     </c:when>  
  53.                     <c:otherwise>  
  54.                         <input type="text" id="view.currentPage" name="currentPage"  
  55.                             value="${view.currentPage }" />  
  56.                     </c:otherwise>  
  57.                 </c:choose> <strong> 页</strong> <a href="javascript:toPageGo(${param.action})">GO</a>  
  58.         </span> <input type="hidden" id="view.thisPage" value="${view.currentPage }" />  
  59.             <input type="hidden" id="view.totalPages" name="totalPages"  
  60.             value="${view.totalPages }"> <input type="hidden"  
  61.             id="view.ascDesc" name="ascDesc" value="${view.ascDesc }"> <input  
  62.             type="hidden" id="view.sortKey" name="sortKey"  
  63.             value="${view.sortKey }"></td>  
  64.   
  65.     </tr>  
  66.   
  67. </table>  

上述页面包含的控件: 

 

那么是如何恢复现场的呢?

也是通过view.

 疑问:

(1)list方法中为什么需要toothOrders 呢,有view 就足够了?

不是的,还需要toothOrders,因为条件查询时,我使用的是Example,所以必须使用ToothOrders对象

 

(2)toothOrders和view 能同时接收到请求要素吗?

是的,这两个对象都会接收到请求要素.要注意,页面表单控件的name不是toothOrders.doctor,而是doctor,这一点与struts2 是不同的.

 

(3)点击[下一页]时是如何保证查询原来的条件呢?

点击[下一步]时,会触发表单提交,同点击[查询]按钮,即会把表单提交,与点击[查询]不同的是:点击查询时会把当前页重置为1(currentPage初始值为1,而不是0).

 点击[上一页]或[下一页]时,应该查询原来的条件.比如我先查询文医生的订单,然后点击
[上一页]或[下一页]应该仍然查询文医生的订单,但是此时我输入其他查询条件,再点击[上一页]或[下一页],那么查询条件就变化了.这就是问题.

界面如下,我先查询订单类型为"正常"的订单:

 然后我在查询条件中添加条件:"
文医生",然后点击[下一页],结果如下:

 确实是进入了第二页,但是原来是共有2324页,但现在只有33页,因为查询条件变化了.但是这是不正常的,
点击[上一页]或[下一页]时查询条件不应该变化.

 

原因:点击[查询]和点击[上一页]或[下一页],触发的是同一个表单提交.

 

但是存在一个问题,点击[上一页]或[下一页]时查询条件应该是原来的.

如何解决这个问题呢?

我的方案如下:点击[查询]时,把查询条件存储到session中,然后点击[上一页]或[下一页]时,表单提交新增一个参数,用于区分点击[查询].

详细方案见下一篇博客.

项目源码见附件demo_channel_terminal.zip

注意:

项目使用spring MVC,hibernate框架,使用maven构建

 

大家可以提出自己的方案,多谢!!!

相关文章
|
8月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
730 1
|
8月前
|
存储 前端开发 Java
【JAVA】Java 项目实战之 Java Web 在线商城项目开发实战指南
本文介绍基于Java Web的在线商城技术方案与实现,涵盖三层架构设计、MySQL数据库建模及核心功能开发。通过Spring MVC + MyBatis + Thymeleaf实现商品展示、购物车等模块,提供完整代码示例,助力掌握Java Web项目实战技能。(238字)
921 0
|
9月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
958 64
|
9月前
|
前端开发 Java 数据库
Java 项目实战从入门到精通 :Java Web 在线商城项目开发指南
本文介绍了一个基于Java Web的在线商城项目,涵盖技术方案与应用实例。项目采用Spring、Spring MVC和MyBatis框架,结合MySQL数据库,实现商品展示、购物车、用户注册登录等核心功能。通过Spring Boot快速搭建项目结构,使用JPA进行数据持久化,并通过Thymeleaf模板展示页面。项目结构清晰,适合Java Web初学者学习与拓展。
556 1
|
10月前
|
缓存 NoSQL Java
Java Web 从入门到精通之苍穹外卖项目实战技巧
本项目为JavaWeb综合实战案例——苍穹外卖系统,涵盖Spring Boot 3、Spring Cloud Alibaba、Vue 3等主流技术栈,涉及用户认证、订单处理、Redis缓存、分布式事务、系统监控及Docker部署等核心功能,助你掌握企业级项目开发全流程。
977 0
|
10月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
822 0
|
12月前
|
SQL Java 数据库连接
Java中实现SQL分页的方法
无论何种情况,选择适合自己的,理解了背后的工作原理,并能根据实际需求灵活变通的方式才是最重要的。
285 9
|
网络协议 Java Shell
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
1012 7
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
1022 7
Spring Boot 入门:简化 Java Web 开发的强大工具
|
Kubernetes Java 持续交付
小团队 CI/CD 实践:无需运维,Java Web应用的自动化部署
本文介绍如何使用GitHub Actions和阿里云Kubernetes(ACK)实现Java Web应用的自动化部署。通过CI/CD流程,开发人员无需手动处理复杂的运维任务,从而提高效率并减少错误。文中详细讲解了Docker与Kubernetes的概念,并演示了从创建Kubernetes集群、配置容器镜像服务到设置GitHub仓库Secrets及编写GitHub Actions工作流的具体步骤。最终实现了代码提交后自动构建、推送镜像并部署到Kubernetes集群的功能。整个过程不仅简化了部署流程,还确保了应用在不同环境中的稳定运行。
1036 9