一 分页查询
常用的分页查询f
1. 使用subList()实现分页。
List<E> subList(int fromIndex,int toIndex)
返回列表中指定的fromIndex(包含)和 toIndex (不包括)之间的部分视图。
2. 使用SQL语句实现分页
利用数据库自带的分页语法,使用分页语句,获取分页数据(例如mysql数据库使用limit关键字,oracle中使用rownum关键字等)
3. 使用hibernate框架进行分页。
创建Query或者Criteria对象,查询时,设置firstResult(从第几条开始查)和maxResults(查询几条记录)属性。
下面介绍一下 MySQL数据库中使用limit关键字的web查询方式;
简单写下思路:
分页查询
DAO层
arrayList findList(beginPage PageSize)
限制起始页(beginPage),每页显示多少条数据(PageSize)
serivec 层
调DAO层方法
pageSize = xx
当前页currentPage = 1
起始页beginPage =(currentPage - 1)* PageSize
totalPage =(Count%pageSize)?(Count / pageSize):(计数/页面大小+1)
注意:将要返回的值封装到一个对象中
servlet的层
获取参数:currentPage(点击上一页下一页)点击上一页下一页
默认当前页currentPage = 1;
调服务层方法:封装好的对象PageBean
请分发:把封装好的对象保存到域中
转发到JSP页面显示数据
pageBean 对象类:
package com.lanpu3g;
import java.util.ArrayList;
public class PageBean {
//当前页
private int currentPage;
//每页显示多少条数据
private int pageSize;
//总记录数
private int count;
//总页数
private int totalPage;
//保存数据的集合
private ArrayList<Sort> sorts;
public PageBean() {
super();
// TODO Auto-generated constructor stub
}
public PageBean(int currentPage, int pageSize, int count, int totalPage, ArrayList<Sort> sorts) {
super();
this.currentPage = currentPage;
this.pageSize = pageSize;
this.count = count;
this.totalPage = totalPage;
this.sorts = sorts;
}
@Override
public String toString() {
return "PageBean [currentPage=" + currentPage + ", pageSize=" + pageSize + ", count=" + count + ", totalPage="
+ totalPage + ", sorts=" + sorts + "]";
}
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 getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public ArrayList<Sort> getSorts() {
return sorts;
}
public void setSorts(ArrayList<Sort> sorts) {
this.sorts = sorts;
}
}
Servlet 层
package com.lanpu3g;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
//获取参数
int currentPage = 1;
String currentPageStr = request.getParameter("currentPage");
//每页显示多少条数据
int pageSize = 3;
if (currentPageStr!=null) {
currentPage = Integer.parseInt(currentPageStr);
}
//调逻辑层方法
ListService service = new ListService();
PageBean pageBean = service.findList(pageSize,currentPage);
//跳转页面
request.setAttribute("pageBean", pageBean);
request.getRequestDispatcher("/list.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
service 层
package com.lanpu3g;
import java.sql.SQLException;
import java.util.ArrayList;
public class ListService {
private static ListDao dao = new ListDao();
//分页查询
public PageBean findList(int pageSize, int currentPage) {
// 调用dao 层方法 返回一个查询的集合
int beginPage = (currentPage - 1) * pageSize;
//获取总的记录数
int count =0;
try {
count = dao.getCount();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int totalPage = (count % pageSize==0) ? (count / pageSize ) : (count / pageSize +1 );
ArrayList<Sort> sorts = null;
try {
sorts = dao.findList(pageSize,beginPage);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PageBean pageBean = new PageBean(currentPage, pageSize, count, totalPage, sorts);
return pageBean;
}
}
dao 层
package com.lanpu3g;
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;
public class ListDao {
private QueryRunner runner = new QueryRunner(DataSourceUtil.getDataSource());
//获取总记录数
public int getCount() throws SQLException {
String sql = "select count(*) from sort";
Long count = runner.query(sql, new ScalarHandler<>());
return count.intValue();
}
//分页查询
public ArrayList<Sort> findList(int pageSize, int beginPage) throws SQLException {
String sql = "select * from sort limit ?,?";
Object [] params = {beginPage,pageSize};
ArrayList<Sort> sorts =(ArrayList<Sort>) runner.query(sql, new BeanListHandler<>(Sort.class), params);
return sorts;
}
}
数据库连接工具类
package com.lanpu3g;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
public class DataSourceUtil {
private static BasicDataSource dataSource = new BasicDataSource();
static {
InputStream stream = DataSourceUtil.class.getClassLoader().getResourceAsStream("dbinfo.properties");
Properties properties = new Properties();
try {
properties.load(stream);
dataSource.setDriverClassName(properties.getProperty("driverClass"));
dataSource.setUrl(properties.getProperty("url"));
dataSource.setUsername(properties.getProperty("user"));
dataSource.setPassword(properties.getProperty("password"));
dataSource.setMaxActive(Integer.parseInt(properties.getProperty("maxActive")));
dataSource.setInitialSize(Integer.parseInt(properties.getProperty("initialSize")));
dataSource.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle")));
dataSource.setMinIdle(Integer.parseInt(properties.getProperty("minIdle")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private DataSourceUtil() {
// TODO Auto-generated constructor stub
}
public static DataSource getDataSource() {
return dataSource;
}
}
listjsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1" cellspacing="0">
<tr>
<td>商品名称</td>
<td>商品价格</td>
<td>商品描述</td>
</tr>
<c:forEach items="${pageBean.sorts }" var="sort" >
<tr>
<td>${sort.sname }</td>
<td>${sort.sprice }</td>
<td>${sort.sdesc }</td>
</tr>
</c:forEach>
</table>
<!-- 上一页 第几页 共几页 下一页 -->
<a href="${pageContext.request.contextPath }/listServlet?currentPage=${pageBean.currentPage==1?1:pageBean.currentPage-1 }"> 上一页</a>
第 ${pageBean.currentPage } 页 共 ${pageBean.totalPage } 页
<a href="${pageContext.request.contextPath }/listServlet?currentPage=${pageBean.currentPage==pageBean.totalPage?pageBean.totalPage:pageBean.currentPage+1 }"> 下一页</a>
</body>
</html>
二 监听器
一: 什么是web监听器?
web监听器是一种Servlet中的特殊的类,它们能帮助开发者监听web中的特定事件,比如ServletContext,HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控。
二 监听器的用途?
统计在线人数,利用HttpSessionLisener
加载初始化信息:利用ServletContextListener
统计网站访问量
实现访问监控
三 监听器的分类
1.监听域对象的创建和销毁:
--ServletContextListener : ServletContext监控:对应监控application内置对象的创建和销毁;
--HttpSessionListener: HttpSession监控:对应监控session内置对象的创建和销毁;
--ServletRequestListener :ServletRequest监控:对应监控request内置对象的创建和销毁;
举个例子:监听 httpSession 对象的创建和销毁 : 实现接口 HttpSessionListener;
package com.lanou3g;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
//HttpSessionEvent Session 的事件对象
HttpSession session = se.getSession();
String id = session.getId();
System.out.println(id + "创建了");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session 销毁了");
}
}
当浏览器访问jsp时 系统打印
A5AD399CD5908906E92141553545BF22创建了
2.监听属性的新增、删除和修改:
--ServletContextAttributeListener :
通过调用ServletContextAttribtueEvent的getName方法可以得到属性的名称。
public class MyServletContextAttrListener implements ServletContextAttributeListener{
public void attributeAdded(ServletContextAttributeEvent hsbe) {
System.out.println("In servletContext added :name = "+hsbe.getName());
}
public void attributeRemoved(ServletContextAttributeEvent hsbe) {
System.out.println("In servletContext removed :name = "+hsbe.getName());
}
public void attributeReplaced(ServletContextAttributeEvent hsbe) {
System.out.println("In servletContext replaced :name = "+hsbe.getName());
}
}
--HttpSessionAttributeListener:
public class MyHttpSessionAttrListener implements HttpSessionAttributeListener{
public void attributeAdded(HttpSessionBindingEvent hsbe) {
System.out.println("In httpsession added:name = "+hsbe.getName());
}
public void attributeRemoved(HttpSessionBindingEvent hsbe) {
System.out.println("In httpsession removed:name = "+hsbe.getName());
}
public void attributeReplaced(HttpSessionBindingEvent hsbe) {
System.out.println("In httpsession replaced:name = "+hsbe.getName());
}
}
--ServletRequestAttributeListener: 同以上两个;
3.监听对象的状态:
需求 : 定时销毁session 5秒销毁一次
package com.lanou3g;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/*
* 练习:
* 需求 ?:定时销毁session 5秒销毁一次
* 思路:
* ---保存在哪?
* 1.把所有创建出来的session 对象 保存到 ServletContext
* 把所有session 对象存在数组里 然后在把数组 保存进域中
* ---什么时候创建数组?
* 当 ServletContext 对象初始化的时候 创建数组;
* ---什么时候把session对象放到数组中
* 当 session 对象创建时 放进数组中;
* 2.遍历所有保存起来的session对象
* 查看session 5秒没有的 就让该session失效
* system.currentTimeMillis();
* - session.getLastAccessedTime() = 5000
* 获取最后session 没使用的时间 到1970年1.1 没使用时间的毫秒数
*/
public class Demo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
System.out.println(session.getId()+"被创建了");
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.lanou3g;
import java.util.ArrayList;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
//获取context 域 取出数组
ArrayList<HttpSession> list =(ArrayList<HttpSession>)se.getSession().getServletContext().getAttribute("list");
//把创建好的session对象放入数组中
list.add(se.getSession());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
// TODO Auto-generated method stub
HttpSessionListener.super.sessionDestroyed(se);
}
}
package com.lanou3g;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//创建保存sesssion 数组
ArrayList<HttpSession> list = new ArrayList<>();
ServletContext servletContext = sce.getServletContext();
//把数组存入域中
servletContext.setAttribute("list", list);
//当保存session 数组被创建出来
//就开始 每隔一秒中检查一次
//有没有超过5秒的session 将它移除
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("扫描中.........");
//使用迭代器遍历集合
Iterator<HttpSession> iterator = list.iterator();
while (iterator.hasNext()) {
HttpSession session = iterator.next();
//计算时间
Long time = System.currentTimeMillis() -session.getLastAccessedTime();
//判断时间
if (time>5000) {
//让session失效
session.invalidate();
//从数组中删除该session
iterator.remove();
System.out.println(session.getId()+"被移除了");
}
}
}
}, 2000, 1000);
}
}
注意:监听器的使用需要在web.XML 文件内配置,另外HttpSessionBindingListener不需要对web.XML文件配置但是该接口需要被绑定的对象的来实现;
三 过滤器
1.什么是过滤器
过滤器JavaWeb三大组件之一,它与Servlet很相似!不过滤器是用来拦截请求的,而不是处理请求的。当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。
2.过滤器实现步骤:
1.实现Filter接口
2.实现方法(生命周期方法 doFilter 拦截方法)
3.配置XML文件: 配置要过滤的路径 一般使用 /*
练习 :
利用过滤器自动登录
登录过一次 关闭浏览器(结束此次对话)
当在访问该网站 会自动登录
1.从cookie中取出账号密码
2.创建service 调用service中登录方法
返回一个user对象
如果user不为空 登录成功了
dao层
package com.lanou3g;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
public class UserDao {
private QueryRunner runner = new QueryRunner(DataSourceUtil.getDataSource());
public User findUser(User user) throws SQLException {
String sql = "select * from users where username = ? and password = ?";
Object [] obj = {user.getUsername(),user.getPassword()};
User u = runner.query(sql, new BeanHandler<>(User.class), obj);
return u;
}
}
service 层
package com.lanou3g;
import java.sql.SQLException;
public class UserSerivice {
private UserDao dao = new UserDao();
public User findUser(User user) {
User u = null;
try {
u = dao.findUser(user);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return u;
}
}
servlet 层
package com.lanou3g;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
//获取参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//获取自动登录的值
String autologin = request.getParameter("autologin");
User user = new User();
user.setUsername(username);
user.setPassword(password);
//调用逻辑层方法
UserSerivice service = new UserSerivice();
User u = service.findUser(user);
//跳转页面
if (u!=null) {
//处理cookie 将账号密码拼接进去
Cookie cookie = new Cookie("user", username+"&"+password);
cookie.setPath("/");
//判断是否点了自动登录
if (autologin!=null) {
//点了 设置cookie的保存时间
cookie.setMaxAge(Integer.MAX_VALUE);
}else {
//没点 删除cookie
cookie.setMaxAge(0);
}
//将cookie添加到响应中
response.addCookie(cookie);
//登录成功
request.getSession().setAttribute("user", u);
request.getRequestDispatcher("/home.jsp").forward(request, response);
}else {
//登录失败
request.setAttribute("msg", "登录失败");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
过滤器
package com.lanou3g;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/*
* 处理自动登录
*/
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 把参数转化成 HttpServletRequest
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
//直接 home.jsp ---拦截
//直接 login.jsp ---不拦截
//通过请求 获取请求的网址进行判断 http://localhost:8080/sh-web-autoLogin/loginServlet
String uri = req.getRequestURI();//sh-web-autoLogin/loginServlet
String path = req.getContextPath();///sh-web-autoLogin
String url = uri.substring(path.length());// /login.jsp
//判断网址 处理自动登录
if (!url.equals("/login.jsp")) {
//自动登录 没登录过 才去自动登录
//获取session 判断里面有没有user
HttpSession session = req.getSession();
User user =(User) session.getAttribute("user");
if (user==null) {
//进行自动登录
Cookie[] cookies = req.getCookies();
if (cookies!=null) {
String username = "";
String password = "";
//遍历cookies
for (Cookie cookie : cookies) {
//判断
if (cookie.getName().equals("user")) {
//取出对应的值 wanglong&123
String value = cookie.getValue();
String[] values = value.split("&");
username = values[0];
password = values[1];
}
}
// 自动登录
UserSerivice serivice = new UserSerivice();
User u = new User();
u.setUsername(username);
u.setPassword(password);
User findUser = serivice.findUser(u);
if (findUser!=null) {
//进行自动登录 把值放进session中
req.getSession().setAttribute("user", findUser);
}
}
}
}
//放行
chain.doFilter(request, response);
}
}
XML配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>sh-web-autoLogin</display-name>
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.lanou3g.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.lanou3g.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
JSP省略: