Ajax无刷新分页

时间:2022-12-09 15:37:45


技术重点主要是XML文档的读写操作。因为前台页面与后台数据分页是使用XML文档进行交互的。本实例将主要介绍DOM技术如何生成XML文档。

代码如下:

try {
// 创建XML文档构建工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
// 创建XML文档构建对象
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
doc = documentBuilder.newDocument(); // 创建文档对象
} catch (ParserConfigurationException ex) {
Logger.getLogger(AjaxFenyeService.class.getName()).log(Level.SEVERE, null, ex);
}
Element createElement(String tagName)
tagName:节点的名称。
appendChild(Node newChild)
newChild:Node接口的实现对象,Element类实现了Node接口,所以Element类的实例对象可以直接作为该方法的参数。
Element root = doc.createElement("products"); // 创建XML的根节点
doc.appendChild(root); // 添加根节点到xml文档
PageArgs pageArgs = dao.getPageArgs(); // 获取数据分页参数
pageArgs.setPageCount(page); // 设置当前分页页码
Element pageArg = doc.createElement("pageArg"); // 创建分页信息节点
root.appendChild(pageArg); // 添加分页信息到根节点
Element pageNumElement = doc.createElement("pageNum");// 添加当前页码参数
pageArg.appendChild(pageNumElement);
public DOMSource(Node node)
node:该参数是DOM节点对象,它作为输入源。
public abstract void transform(Source xmlSource,
Result outputTarget)
xmlSource:DOM数据源
outputTarget:保存XML文档的输出流
// 创建XML转换器
Transformer tf = TransformerFactory.newInstance().newTransformer();
OutputStream out = resp.getOutputStream(); // 获取应答输出流
DOMSource ds = new DOMSource(doc); // 创建XML数据源
StreamResult stream = new StreamResult(out);
tf.setOutputProperty(OutputKeys.INDENT, "yes"); // 缩进XML文档格式
tf.transform(ds, stream); // 把数据输出到浏览器
out.close();

*******编写index.jsp首页文件,在首页文件中添加<label>标签,设置该标签的id属性为“productList”,它用于保存分页数据。关键代码如下:
<body onload="requestPage(1)">
<h1>明日科技部分图书介绍列表</h1>
<label id="productList"></label>
</body>

********在页面中编写JavaScript脚本,创建requestPage()方法,该方法用于创建请求对象,向服务器发送获取分页数据的请求,同时设置服务器返回的数据由readPage()方法处理。关键代码如下。
<script type="text/javascript">
var xmlHttp;
function requestPage(page){
//初始化对象并发出XMLHttpRequest请求
if (window.XMLHttpRequest) { // Mozilla或其他除IE以外的浏览器
xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE浏览器
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!xmlHttp) {
alert("不能创建XMLHTTP实例!");
return false;
}
xmlHttp.onreadystatechange = readPage; // readPage()方法处理服务器响应
xmlHttp.open("GET", "fenyeService?page="+page,true); // 发送请求对象
xmlHttp.send(null);
}

*******编写脚本的readPage()方法,服务器返回的分页数据是XML文档格式,该方法在服务器正确返回分页数据时解析XML文档将指定页面数据和分页参数信息添加到页面的<label>标签中,这样就只更新<label>标签中的数据,而不用重新加载整个页面。关键代码如下
function readPage(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
var doc=xmlHttp.responseXML; // 接收XML文档对象
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 products = doc.getElementsByTagName("product"); // 获取所有分页数据
var innerHTML = ""; // 定义插入<label>标签的数据
if((products!=null)&&(products.length!=0)) {
innerHTML+="<table border=1 width='600'>"; // 插入表头信息
innerHTML+="<tr align='center'><th>ISBN</th><th>书名</th>";
innerHTML+="<th>作者</th><th>出版社</th>";
innerHTML+="<th>单价</th><th>出版日期</th></tr>";
for(var i=0;i<products.length;i++) { // 遍历XML文档的所有图书
var product = products[i];
var isbn = product.childNodes[0].firstChild.data;
var bookName = product.childNodes[1].firstChild.data;
var writer = product.childNodes[2].firstChild.data;
var publishing = product.childNodes[3].firstChild.data;
var price = product.childNodes[4].firstChild.data;
var date = product.childNodes[5].firstChild.data;
innerHTML += "<tr>";
innerHTML += "<td>"+isbn+"</td>"; // 把图书信息插入表格
innerHTML += "<td>"+bookName+"</td>";
innerHTML += "<td>"+writer+"</td>";
innerHTML += "<td>"+publishing+"</td>";
innerHTML += "<td>"+price+"</td>";
innerHTML += "<td>"+date+"</td>";
innerHTML += "</tr>";
}
innerHTML+="<tr><td align='center' colspan='6'>"; // 添加分页超链接
innerHTML += "<a href=\"javascript:void(0)\" onClick=\"requestPage(1)\">第一页</a>";
innerHTML += "<a href=\"javascript:void(0)\" onClick=\"requestPage("+prePage+")\">上一页</a>";
innerHTML += pageNum+"/"+maxPage;
innerHTML += "<a href=\"javascript:void(0)\" onClick=\"requestPage("+nextPage+")\">下一页</a>";
innerHTML +="<a href=\"javascript:void(0)\" onClick=\"requestPage("+maxPage+")\">尾页</a>";
innerHTML+="</td></tr>\n";
innerHTML+="</table>\n";
}else {
innerHTML += "暂时没有任何数据";
}
document.getElementById("productList").innerHTML = innerHTML;
} else {
alert('您请求的页面发现错误');
}
}
}

********编写AjaxFenyeService类,它是处理分页请求的Servlet控制器,该类重写Servlet的doGet()方法,处理分页请求,该方法首先创建XML文档对象,从数据库读取分页参数信息并添加到XML文档对象的根节点中。关键代码如下
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
// 创建XML文档构建工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
// 创建XML文档构建对象
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
doc = documentBuilder.newDocument(); // 创建文档对象
} catch (ParserConfigurationException ex) {
Logger.getLogger(AjaxFenyeService.class.getName()).log(Level.SEVERE, null, ex);
}
List books = null; // 创建数据集合
resp.setContentType("application/xml"); // 设置应答类型为XML
// 获取请求对象的分页参数
int page = ServletRequestUtils.getIntParameter(req, "page", 1);
Element root = doc.createElement("products"); // 创建XML的根节点
doc.appendChild(root); // 添加根节点到xml文档
PageArgs pageArgs = dao.getPageArgs(); // 获取数据分页参数
pageArgs.setPageCount(page); // 设置当前分页页码
Element pageArg = doc.createElement("pageArg"); // 创建分页信息节点
root.appendChild(pageArg); // 添加分页信息到根节点
Element pageNumElement = doc.createElement("pageNum"); // 添加当前页码参数
pageArg.appendChild(pageNumElement);
Text pageNumValue = doc.createTextNode(pageArgs.getPageNum() + "");
pageNumElement.appendChild(pageNumValue);
// 添加最大页码参数
Element maxPageElement = doc.createElement("maxPage");
pageArg.appendChild(maxPageElement);
Text maxPageValue = doc.createTextNode(pageArgs.getMaxPage() + "");
maxPageElement.appendChild(maxPageValue);
// 添加下一页的页码参数
Element nextPageElement = doc.createElement("nextPage");
pageArg.appendChild(nextPageElement);
Text nextPageValue = doc.createTextNode(pageArgs.getNextPage() + "");
nextPageElement.appendChild(nextPageValue);
// 添加上一页的页码参数
Element prePageElement = doc.createElement("prePage");
pageArg.appendChild(prePageElement);
Text prePageValue = doc.createTextNode(pageArgs.getPrePage() + "");
prePageElement.appendChild(prePageValue);
try { // 添加图书节点
books = dao.getProducts(page);
for (Object pro : books) {
FenyeBean fenyeBean = (FenyeBean) pro;
Element product = doc.createElement("product");
root.appendChild(product);
Element isbnNode = doc.createElement("ISBN"); // 创建ISBN节点
product.appendChild(isbnNode);
Text isbnValue = doc.createTextNode(fenyeBean.getIsbn());
isbnNode.appendChild(isbnValue);
Element nameNode = doc.createElement("BookName"); // 创建bookname节点
product.appendChild(nameNode);
Text nameValue = doc.createTextNode(fenyeBean.getBookName());
nameNode.appendChild(nameValue);
Element writerNode = doc.createElement("Writer"); // 创建Writer节点
product.appendChild(writerNode);
Text writerValue = doc.createTextNode(fenyeBean.getWriter());
writerNode.appendChild(writerValue);
Element pbNode = doc.createElement("Publishing"); // 创建publishing节点
product.appendChild(pbNode);
Text pbValue = doc.createTextNode(fenyeBean.getPublishing());
pbNode.appendChild(pbValue);
Element priceNode = doc.createElement("Price"); // 创建Price节点
product.appendChild(priceNode);
Text priceValue = doc.createTextNode(fenyeBean.getPrice()+"");
priceNode.appendChild(priceValue);
Element dateNode = doc.createElement("Date"); // 创建Date节点
product.appendChild(dateNode);
Text dateValue = doc.createTextNode(fenyeBean.getDate().toLocaleString());
dateNode.appendChild(dateValue);
}
// 创建XML转换器
Transformer tf = TransformerFactory.newInstance().newTransformer();
OutputStream out = resp.getOutputStream(); // 获取应答输出流
DOMSource ds = new DOMSource(doc); // 创建XML数据源
StreamResult stream = new StreamResult(out);
tf.setOutputProperty(OutputKeys.INDENT, "yes"); // 缩进XML文档格式
tf.transform(ds, stream); // 把数据输出到浏览器
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public class PageArgs {
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);
}
……省略部分代码
}
public PageArgs getPageArgs() {
PageArgs pag = null; // 声明分页参数对象
Statement stmt = null;
ResultSet rs = null;
Connection conn = getConn(); // 连接数据库
try {
// 声明查询总数据量的SQL语句
String sql = "SELECT count(*) FROM tb_hibernatefenye";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql); // 执行SQL查询
if (rs.next()) {
int count = rs.getInt(1); // 获取查询结果
pag = new PageArgs(); // 初始化分页参数对象
pag.setPageSize(pageSize); // 设置分页大小
pag.setMaxPage((count + pageSize - 1) / pageSize); // 设置最大页码
pag.setPageCount(count); // 设置当前页码
}
} catch (SQLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
close(rs, stmt, conn);
}
return pag;
}
public List getProducts(final int page) throws Exception {
if (pageSize == 0) {
throw new Exception("产品分页的页面大小不能为0");
}
List list = new ArrayList(); // 创建保存分页数据的集合对象
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn = getConn(); // 连接数据库
try {
// 定义分页查询的SQL语句
String sql = "SELECT * FROM tb_Databasetoexcel limit ?,?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, (page-1)*pageSize); // 设置SQL查询参数
stmt.setInt(2, pageSize); // 设置SQL查询参数
rs = stmt.executeQuery(); // 获取查询结果
while (rs.next()) { // 遍历查询结果集
FenyeBean fenyeBean = new FenyeBean(); // 创建分页对象
fenyeBean.setIsbn(rs.getString("isbn")); // 初始化分页对象
fenyeBean.setBookName(rs.getString("bookName"));
fenyeBean.setPublishing(rs.getString("publishing"));
fenyeBean.setWriter(rs.getString("writer"));
fenyeBean.setPrice(rs.getFloat("price"));
fenyeBean.setDate(rs.getDate("date"));
list.add(fenyeBean); // 添加分页数据对象到List集合
}
} catch (SQLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
close(rs, stmt, conn);
}
return list;
}