Java进阶之Aiax无刷新分页知识点总结
2014-12-03 22:17
495 查看
实例说明 在Web应用开发中,经常需要对信息进行分页显示。本实例将介绍如何应用Ajax实现无刷新分页。运行本实例,如图1所示,单击信息列表下面的“首 页”、“上一页”、“下一页”以及“尾页”超链接时,可以显示不同的信息,此时整个页面不刷新。
图1 实现无刷新分页
关键技术
本实例主要应用Ajax异步提交来实现。当单击超链接时,需要将当前页的页码参数值通过Ajax请求方法发送到服务器,在服务器中根据获得的参数值获取不同的分页数据,然后将这些分页数据以XML文档格式响应给客户端页面。客户端通过Ajax回调函数来读取XML文档内容,将这些内容替换页面信息列表中原来的显示内容,而不改变页面其他内容,从而实现页面的无刷新分页。 设计过程 (1)创建request.js文件,用于封装Ajax请求服务器的方法。 (2)创建商品信息列表页index.jsp,在该页中通过<script>标签导入封装Ajax请求的request.js文件,然后在<script>标签中定义一个用于接收Ajax请求方法所返回的XMLHttpRequest对象的变量。创建JavaScript方法getData(),在该方法中调用request.js文件中的Ajax请求方法请求目标服务器。关键代码如下:
<script language="javascript" src="js/request.js"></script> <script language="javascript"> var request = false; //保存 XMLHttpRequest对象的全局变量 //Ajax请求方法 function getData(page){ var url="GoodsServlet"; //服务器地址 var param ="page="+page+"&nocache="+new Date().getTime();//请求参数 request=httpRequest("post",url,true,callbackFunc,param);//调用request.js请求方法 }
(3)创建Servlet的实现类GoodsServlet,用于获取商品信息。在该类的doPost()方法中接收到Ajax请求中的page参数值,然后设置响应正文的MIME类型为XML格式,从数据库中读取出商品信息以及分页信息添加到XML的节点中,最后将XML格式的信息输出到客户端。doPost()方法的具体代码如下:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType( "text/xml;charset=UTF-8" );//设置响应格式为test/xml //设置response.addHeader(),禁止页面缓存 response.addHeader( "Cache-Control", "no-store,no-cache,must-revalidate" ); response.addHeader( "Cache-Control", "post-check=0,pre-check=0" ); response.addHeader( "Expires", "0" ); response.addHeader( "Pragma", "no-cache" ); PrintWriter out = response.getWriter(); PageElement pageArgs = getPageArgs(); // 获取数据分页参数 List goodses = null; // 创建保存商品信息的数据集合 // 获取请求对象的分页参数 int page=1; if(null!=request.getParameter("page")){ page = Integer.parseInt(request.getParameter("page")); } pageArgs.setPageCount(page); out.println( "<?xml version=\"1.0\" encoding=\"utf-8\"?>" ); out.println( "<goodses>" ); out.println( "<pageElement>" ); out.println( "<pageNum>" +pageArgs.getPageNum()+"</pageNum>"); out.println( "<maxPage>" +pageArgs.getMaxPage()+"</maxPage>"); out.println( "<nextPage>" +pageArgs.getNextPage()+"</nextPage>"); out.println( "<prePage>" +pageArgs.getPrePage()+"</prePage>"); out.println( "</pageElement>" ); try{ goodses = getGoods(page); }catch(Exception e){ e.printStackTrace(); } for(int i=0;i<goodses.size();i++){ CommodityForm commodity = (CommodityForm) goodses.get(i); out.println( "<goods>" ); out.println( "<id>"+commodity.getId()+"</id>" ); out.println( "<goodsName>"+commodity.getGoodsName()+"</goodsName>" ); out.println( "<introduce>"+commodity.getIntroduce()+"</introduce>" ); out.println( "<Price>"+commodity.getPrice()+"</Price>" ); out.println( "</goods>" ); } out.println( "</goodses>" ); out.close(); }
(4)创建PageElement类,用于封装计算分页的参数。关键代码如下:
public class PageElement { private int pageNum; //当前页 private int pageSize; //页面显示数据的条数 private long maxPage; //总页数 private int prePage; //上一页 private int nextPage; //下一页 public void setPageCount(int pageNum) { this.pageNum = pageNum; //设置上一页的页码 prePage=pageNum-1<=1?1:pageNum-1; //设置下一页的页码 nextPage=(int)(pageNum + 1 >= maxPage ? maxPage : pageNum + 1); } ... //此处省略了其他属性的getXXX()和setXXX()方法 }
(5)在GoodsServlet类中,编写获取分页参数信息的getPageArgs()方法,具体代码如下:
public PageElement getPageArgs() { PageElement pag = null; // 声明分页参数对象 Statement stmt = null; ResultSet rs = null; ConnDB conn = new ConnDB(); // 连接数据库 try { // 声明查询总数据量的SQL语句 String sql = "SELECT count(*) FROM tb_goods"; rs = conn.executeQuery(sql); // 执行SQL查询 if (rs.next()) { int count = rs.getInt(1); // 获取查询结果 pag = new PageElement(); // 初始化分页参数对象 pag.setPageSize(pagesize); // 设置分页大小 pag.setMaxPage((count + pagesize - 1) / pagesize);// 设置最大页码 pag.setPageCount(count); // 设置当前页码 } } catch (SQLException ex) { ex.getMessage(); } finally { conn.close(); } return pag; }
(6)在GoodsServlet类中,编写从数据库读取指定商品信息的getGoods()方法,具体代码如下:
public List getGoods(final int page) throws Exception { List list = new ArrayList(); // 创建保存分页数据的集合对象 ConnDB conn = new ConnDB(); // 连接数据库 CommodityForm f =null; int firstResult = (page-1) * pagesize; try { // 定义分页查询的SQL语句 String sql= "select * from tb_goods order by id limit "+firstResult+","+pagesize; ResultSet rs = conn.executeQuery(sql); // 获取查询结果 while (rs.next()) { // 遍历查询结果集 f = new CommodityForm(); // 创建分页对象 f.setId(rs.getInt("id")); f.setGoodsName(rs.getString("name")); f.setIntroduce(rs.getString("introduce")); f.setPrice(rs.getFloat("price")); list.add(f); // 添加分页数据对象到List集合 } } catch (SQLException ex) { ex.printStackTrace(); } finally { conn.close(); } return list; }
7)编写完以上GoodsServlet类中几个方法后,在index.jsp中,需要编写Ajax回调函数callbackFunc(),在回调函数中读取Ajax请求GoodsServlet所响应的XML数据,并添加到指定<span>标签中。callbackFunc()具体代码如下:
function callbackFunc(){ if(request.readyState == 4){ if(request.status == 200){ var doc = request.responseXML; var pageNum = doc.getElementsByTagName("pageNum")[0].firstChild.data; var maxPage= doc.getElementsByTagName("maxPage")[0].firstChild.data; var prePage = doc.getElementsByTagName("prePage")[0].firstChild.data; var nextPage = doc.getElementsByTagName("nextPage")[0].firstChild.data; var goodses = doc.getElementsByTagName("goods"); var innerHTML = ""; if((goodses!=null)&&(goodses.length!=0)) { innerHTML+="<table width='96%' border='1' cellpadding='0' cellspacing='0' bordercolor='#FFFFFF' bordercolordark='#FFFFFF' bordercolorlight='CFCFCF'>"; innerHTML+="<tr align='center' height='30'><td>商品名称</td>"; innerHTML+="<td>简介</td>"; innerHTML+="<td>单价</td></tr>"; for(va b553 r i=0;i<goodses.length;i++) { var goods = goodses[i]; var goodsName = goods.childNodes[1].firstChild.data; var introduce = goods.childNodes[2].firstChild.data; var price = goods.childNodes[3].firstChild.data; innerHTML += "<tr height='30'>"; innerHTML += "<td align='left'> "+goodsName+"</td>"; innerHTML += "<td align='left'> "+introduce+"</td>"; innerHTML += "<td align='left'> "+price+"</td>"; innerHTML += "</tr>"; } innerHTML+="<tr height='30'><td align='center' colspan='6'>"; innerHTML +="["+ pageNum+"/"+maxPage+"] "; innerHTML+="<a href=\"javascript:void(0)\" onClick=\"getData(1)\">[首 页]</a> "; innerHTML+= "<a href=\"javascript:void(0)\" onClick=\"getData("+prePage+")\">[上一页]</a> "; innerHTML+= "<a href=\"javascript:void(0)\" onClick=\"getData("+nextPage+")\">[下一页]</a> "; innerHTML +="<a href=\"javascript:void(0)\" onClick=\"getData("+maxPage+")\">[尾页]</a>"; innerHTML+="</td></tr>\n"; innerHTML+="</table>\n"; }else { innerHTML += "暂时没有任何数据"; } document.getElementById("goodsList").innerHTML = innerHTML; request = false;//此处必须设置XMLHttpRequest对象的变量为初始状态 } } }
(8)在index.jsp页的指定位置添加显示商品列表信息的<span>标签,并设置该标签的id属性为“goodsList”。关键代码如下: <span id="goodsList"></span> (9)在页面加载后就应该请求服务器,读取出初始商品信息。关键代码如下: window.onload=function(){ getData(1); } 秘笈心法 本实例在获得服务器回传的XML数据时,应用到了JavaScript中的DOM对象。在DOM中,HTML文档各个节点被视为各种类型的Node对象,并且将HTML文档表示为Node对象的树,对于任何一个树形结构来说,最常做的就是遍历树。DOM中可以通过Node对象的parentNode属性、firstChild属性、lastChild属性、lastChild属性、previousSibling属性和nextSibling属性来遍历文档树。Node对象的常用属性的具体作用如表1所示。 表1 Node对象的属性
属性 | 类型 | 描述 |
parentNode | Node | 节点的父节点,没有父节点时为null |
childNodes | NodeList | 节点的所有子节点的NodeList |
firstChild | Node | 节点的第一个子节点,没有则为null |
lastChild | Node | 节点的最后一个子节点,没有则为null |
previousSibling | Node | 节点的上一个节点,没有则为null |
nextChild | Node | 节点的下一个节点,没有则为null |
nodeName | String | 节点名 |
nodeValue | String | 节点值 |
nodeType | short | 表示节点类型的整型常量 |
相关文章推荐
- Java进阶之Aiax无刷新分页知识点总结
- Java进阶之Jsp设计模式知识点总结
- Java进阶知识点7:不要只会写synchronized - JDK十大并发编程组件总结
- Java进阶之Jsp找回密码知识点总结
- Java多线程知识点总结——进阶篇(四)之静态同步函数用的是哪一个锁问题
- Java多线程知识点总结——进阶篇(七) 之 等待唤醒机制
- Java进阶之JSP生成条形码知识点总结
- Java进阶之Jsp设计模式知识点总结
- Java进阶之多级联下拉列表知识点总结
- JAVA进阶知识点总结(2)— 包:Package
- Java进阶之验证码知识点总结
- Java进阶之支付宝在线支付知识点总结
- Java进阶之Jsp找回密码知识点总结
- Java多线程知识点总结——进阶篇(十二) 之 Join方法 & 优先级 & yield方法
- Java多线程知识点总结——进阶篇(五)之多线程下的单例模式
- Java进阶之JSP生成条形码知识点总结
- Java进阶之支付宝在线支付知识点总结
- JAVA进阶知识点总结(3)— 多线程
- Java多线程知识点总结——进阶篇(十一) 之 守护线程(后台运行)
- JAVA进阶知识点总结(1)— 异常