整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JSP多条件查询分页

AO数据访问

package dao;
​
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
​
import utils.JdbcUtils;
import utils.PageBean;
import entity.Muli;
​
public class MuliDao {
 // 创建QueryRunner对象
 private QueryRunner qr = JdbcUtils.getQueryRuner();
​
 
 // 查找全部信息列表
 public List<Muli> listMuliAll() {
 String sql = "SELECT * FROM mulihuji ";
 try {
 // 多行数据,封装成对象的集合
 List<Muli> listmuli = qr.query(sql, new BeanListHandler<Muli>(Muli.class));
 return listmuli;
 } catch (Exception e) {
 throw new RuntimeException(e);
 }
 }
 
 // 分页显示全部数据
 public void listMuliAll(PageBean<Muli> pb,Muli muli) throws SQLException {
​
 String countsql = "select count(*) from mulihuji where 1=1";
 String sql = "select * from mulihuji where 1=1";
 
 List<Object> params = new ArrayList<Object>();
 // 添加查询条件
 String xm = muli.getXm();
 if (xm != null && xm != "") {
 countsql += " and xm like ?";
 sql += " and xm like ?";
 params.add("%" + xm + "%");
 }
 String sfzh = muli.getSfzh();
 if (sfzh != null && sfzh != "") {
 countsql += " and sfzh like ?";
 sql += " and sfzh like ?";
 params.add("%" + sfzh + "%");
 } 
 
 //得到总记录数 
 Long count = qr.query(countsql, new ScalarHandler<Long>(),params.toArray());
 pb.setTotalCount(count.intValue());
 /*
 * 问题: jsp页面,如果当前页为首页,再点击上一页报错! 如果当前页为末页,再点下一页显示有问题! 解决: 1. 如果当前页 <= 0;
 * 当前页设置当前页为1; 2. 如果当前页 > 最大页数; 当前页设置为最大页数
 */
 // 判断
 if (pb.getCurrentPage() <= 0) {
 pb.setCurrentPage(1); // 把当前页设置为1
 } else if (pb.getCurrentPage() > pb.getTotalPage()) {
 pb.setCurrentPage(pb.getTotalPage()); // 把当前页设置为最大页数
 }
​
 // 1. 获取当前页: 计算查询的起始行、返回的行数
 int currentPage = pb.getCurrentPage();
 int index = (currentPage - 1) * pb.getPageCount(); // 查询的起始行
 int pagecount = pb.getPageCount(); // 每页的行数
 
 
 sql += " limit ?,?";
 params.add(index);
 params.add(pagecount);
 
 List<Muli> pageData = qr.query(sql, new BeanListHandler<Muli>(Muli.class),params.toArray() ); //获取一页的数据
 // 设置到pb对象中
 pb.setPageData(pageData);
 
​
 }
​
 
}
​

Servlet设计

package servlet;
​
import java.io.IOException;
import java.sql.SQLException;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​
​
import dao.MuliDao;
import entity.Muli;
import utils.PageBean;
​
/**
 * Servlet implementation class QueryListMuliServlet
 */
@WebServlet("/querymuli")
public class QueryListMuliServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
​
 /**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
 
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
 request.setCharacterEncoding("utf-8");
 response.setCharacterEncoding("utf-8");
 String xm = request.getParameter("xm");
 String sfzh = request.getParameter("sfzh");
 //实例化实体类并赋值 
 Muli muli=new Muli();
 muli.setXm(xm);
 muli.setSfzh(sfzh);
 
 //1. 获取“当前页”参数; (第一次访问当前页为null) 
 String currPage = request.getParameter("currentPage");
 // 判断
 if (currPage == null || "".equals(currPage.trim())){
 currPage = "1"; // 若第一次访问,设置当前页为1;
 }
 // 转换为整数型
 int currentPage = Integer.parseInt(currPage);
 //实例化pageben类
 PageBean<Muli> pb = new PageBean<Muli>();
 pb.setCurrentPage(currentPage);
 
 try {
 //调用数据访问的方法,传递两个参数
 MuliDao mulidao = new MuliDao();
 mulidao.listMuliAll(pb,muli);
 
 request.setAttribute("pageBean", pb);
 request.getRequestDispatcher("/querylist.jsp").forward(request, response);
 return;
 
 } catch (SQLException e) {
 e.printStackTrace();
 request.setAttribute("errorMsg", e.getMessage());
 }
 request.getRequestDispatcher("/error.jsp").forward(request, response);
 
 }
​
 /**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 // TODO Auto-generated method stub
 doGet(request, response);
 }
​
}

JSP页面:分为两个页面,1.提交查询条件,2.返回查询结果

期,应客户要求,采集一个旧后台管理系统中的数据列表,并将数据详情保存为HTML文件,旧平台架构为.NET 4.0+easyui,数据列为GridView,这个任务的难点是GridView分页数据抓取的问题,因为切换分页的时候,浏览器的URL是无变化的,包括HTTP请求头部、请求参数、请求URL全是一样,采用常规的方式抓取肯定是行不通的(只能采集到第一页的数据),下面看看我是如何获取分页数据。

废话不多说,直接上代码:

我是基于BeautifulSoup+requests+python3.7实现数据的抓取;

首先设置头部信息,用于保证会话和授权:

headers = {

'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/8.0; .NET4.0C; .NET4.0E)',

'Accept': 'text/html, application/xhtml+xml, image/jxr, */*',

'Content-Type': 'application/x-www-form-urlencoded',

'Accept-Language': 'zh-CN',

'Host': '浏览器F12,根据实际情况填写',

'Cache-Control': 'no-cache',

'Referer': '浏览器F12,根据实际情况填写',

'Cookie': 'ASP.NET_SessionId=浏览器F12,根据实际情况填写'

}

封装网络请求:

def postRequest(url, encoding='utf8', pageno=1):

data = {

'__EVENTTARGET': 'DataPager1',

'__EVENTARGUMENT': f'{pageno}',

'__LASTFOCUS': '',

'GridView1_gesoft_hidScrollOffset': '0,0',

'__VIEWSTATEENCRYPTED': '',

'__VIEWSTATE':'这个必须要填写,否则实现不了分页查询数据',

'__EVENTVALIDATION': '可选,尽量填上',

'HidAddInspectID': '',

'SCAccept$ValueField': '48:105,110,99,108,117,100,101::97,110,100:115,116,114,105,110,103',

'DataPager1_input': f'{pageno}',

'DataPager1$pageSizeList': '10',

'DdlAuthorYear': 'ALL'

}


retryFlag = True

while retryFlag:

retryFlag = False

try:

response = requests.post(url=url, data=data, headers=headers, timeout=10)

response.encoding = encoding

return response

except Exception as e:

print(f'postRequest error({url}) ', e)

retryFlag = True

time.sleep(5)

上述代码中“__VIEWSTATE”参数配置是核心中的核心,这个数据怎么获取呢,我是通过Wireshark抓包工具获取,如下图所示:

请求参数如图所示

为了提高数据采集的稳定性,网络请求增加了超时重试机制。另外特别提醒,请求一定要设置超时时间,否则会导致任务阻塞。

好了,核心部分已经讲完,至于采集到的数据如何用BeautifulSoup进行处理,大家自行在网上查找相关资料,比较简单就不再赘述了。

列表显示数据时,分页显示是必不可少的功能,活不多说,直接干货拿走,django提供了一个分页器Paginator,下面的例子说明如何使用它。


1,写一个带分页功能的查询方法

编辑 myweb\web\views.py文件,加入如下代码


from models import Tasks

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from django.views.decorators import csrf


#任务列表

def task_list(request):

contact_list = Tasks.objects.all().order_by('-task_start_date')

#每页显示25条

paginator = Paginator(contact_list, 25)

page = request.GET.get('page')

try:

contacts = paginator.page(page)

except PageNotAnInteger:

contacts = paginator.page(1)

except EmptyPage:

contacts = paginator.page(paginator.num_pages)


return render(request, 'taskList.html', {'contacts': contacts})


这里是将数据返回到前端页面 taskList.html页面。



2,前端页面获取并显示数据

在myweb\web\templates目录新建一个taskList.html文件,内容如下:

{% extends 'base.html' %}

{% block content %}

<table class="tableList">

<thead>

<tr>

<th>任务名称</th>

<th>操作者</th>

<th>任务描述</th>

<th>开始日期</th>

<th>结束日期</th>

<th>任务评价</th>

</tr>

</thead>

<tbody>

{% if contacts.paginator.count > 0 %}

{% for contact in contacts %}

<tr>

<td> {{ contact.task_name }} </td>

<td> {{ contact.task_user }} </td>

<td> {{ contact.task_describe }}</td>

<td> {{ contact.task_start_date }} </td>

<td> {{ contact.task_end_date }} </td>

<td> {{ contact.task_result }}</td>

</tr>

{% endfor %}

{% else %}

<tr>

<td colspan="10" align="center">没有任务数据</td>

</tr>

{% endif %}

</tbody>

</table>



{# 分页HTML代码 #}

<div class="pagination">

<span class="step-links">

{% if contacts.has_previous %}

<a href="?page={{ contacts.previous_page_number }}">上一页</a>

{% endif %}


<span class="current">

Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.

</span>


{% if contacts.has_next %}

<a href="?page={{ contacts.next_page_number }}">下一页</a>

{% endif %}

</span>

</div>

{% endblock %}


3,URL映射

编辑urls.py文件,加入:


url(r'^tasklist/', views.task_list),