
回顾
1. filter作用
拦截用户的请求,完成一些通用的操作:统一网站编码、非法字符拦截(过滤)
2. filter快速入门
1)编写普通类,实现filter接口
2)重写抽象方法(doFilter)
3)配置
web.xml【推荐】
注解
3. filter工作原理
4. filter细节
生命周期
在服务器启动时,创建filter,执行init方法
在服务器关闭时,销毁filter,执行destroy方法
用户每次访问被拦截资源时,执行doFilter方法
拦截路径
精准匹配 /show.jsp
目录匹配 /user/*
后缀匹配 *.html
匹配所有 /*
拦截方式
request(默认):用户直接访问时拦截
forward:内部资源转发时拦截
过滤器链
当多个过滤器拦截同一个目标资源时,我们会形成一个链条
执行顺序:先进后出
执行先后:
web.xml 谁先声明,谁先执行
注解 根据类名,值小的先执行
5. filter综合案例
用户留言
中文处理
非法拦截
非法过滤
Listener&综合案例
今日目标
1. listener(了解)
统计在线人数
2. 用户模块增删改查(重点)
bootstrap前端布局框架
一 Listener【了解】
1.1 概述
生活中的监听器
我们很多商场有摄像头,监视着客户的一举一动。如果客户有违法行为,商场可以采取相应的措施。
观察者模式
javaweb中的监听器
在我们的java程序中,有时也需要监视某些事情,一旦被监视的对象发生相应的变化,我们应该采取相应的操作。
监听web三大域对象:HttpServletRequest、HttpSession、ServletContext (创建和销毁)
场景
历史访问次数、统计在线人数、系统启动时初始化配置信息
1.2 快速入门
监听器在web开发中使用的比较少,见的机会就更少了,今天我们使用ServletContextListenner来带领大家学习下监听器,因为这个监听器是监听器中使用率最高的一个,且监听器的使用方式都差不多。
我们使用这个监听器可以在项目启动和销毁的时候做一些事情,例如,在项目启动的时候加载配置文件。
步骤分析
1. 创建一个普通类,实现ServletContextListenner
2. 重写抽象方法
监听ServletContext创建
监听ServletContext销毁
3. 配置
web.xml
注解
4. 补充
监听HttpServletRequestListener,用户每次访问时,触发创建
监听HttpSessionListener,浏览器建立会话时,触发创建
① xml版本
public class MyListener implements ServletContextListener {
// 监听ServletContext创建
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext已经创建了...");
}
// 监听ServletContext销毁
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext已经销毁了....");
}
}
<listener>
<listener-class>cn.itcast.a_quick.MyListener</listener-class>
</listener>
② 注解版本
@WebListener
public class MyListener implements ServletContextListener {
// 监听ServletContext创建
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext已经创建了...");
}
// 监听ServletContext销毁
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext已经销毁了....");
}
}
1.3 扩展:模拟spring框架
- 可以在项目启动时读取配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--全局配置参数-->
<context-param>
<param-name>configLocation</param-name>
<param-value>words.properties</param-value>
</context-param>
</web-app>
@WebListener
public class MyListener implements ServletContextListener {
// 监听ServletContext创建
/*
ServletContextEvent 上下文事件对象,获取ServletContext
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext已经创建了...");
// 通过servletContextEvent获取上下文对象
ServletContext servletContext = servletContextEvent.getServletContext();
// 我可以去加载公司定义配置文件的名称....
String configLocation = servletContext.getInitParameter("configLocation");
System.out.println("动态获取配置文件名称:" + configLocation);
}
// 监听ServletContext销毁
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext已经销毁了....");
}
}
1.4 案例:统计在线人数
需求
有用户使用网站,在线人数就+1;用户退出网站,在线人数就-1
1.4.1 技术分析
使用 ServletContext域对象 存储在线总人数
使用 ServletContextListener监听器,在项目启动时,初始化总人数为0
使用 HttpSessionListener监听器,用户访问,人数+1,用户退出,人数-1
使用 LogoutServlet控制器,对当前会话的session销毁
1.4.2 需求分析

1.4.3 代码实现
① InitNumberListener
@WebListener
public class InitNumberListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 获取上下文域对象
ServletContext servletContext = servletContextEvent.getServletContext();
// 初始化在线人数
servletContext.setAttribute("number", 0);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
② NumberChangeListener
@WebListener
public class NumberChangeListener implements HttpSessionListener {
// 会话建立,在线人数+1
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
// 获取session域对象
HttpSession session = httpSessionEvent.getSession();
// 获取上下文域对象
ServletContext servletContext = session.getServletContext();
// 取出在线人数
Integer number = (Integer) servletContext.getAttribute("number");
// +1
servletContext.setAttribute("number", number + 1);
}
// 会话销毁,在线人数-1
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
// 获取session域对象
HttpSession session = httpSessionEvent.getSession();
// 获取上下文域对象
ServletContext servletContext = session.getServletContext();
// 取出在线人数
Integer number = (Integer) servletContext.getAttribute("number");
// -1
servletContext.setAttribute("number", number - 1);
}
}
③ index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>${NAME}</title>
</head>
<body>
<h3>listener知识学习</h3>
<h5>在线人数:${applicationScope.number}</h5>
<a href="${pageContext.request.contextPath}/LogoutServlet">用户退出</a>
</body>
</html>
④ LogoutServlet
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 销毁session
request.getSession().invalidate();
response.getWriter().write("logout");
}
}
二 综合案例【重点】
回顾web核心技术栈
1. servlet
2. request
3. response
4. cookie
5. session
6. jsp
7. filter
8. listener
9. servletContext
目标:以用户模块举例,实现web核心技术栈综合运用
老师要求:大家课下看一下页面原型
2.1 环境搭建
- 要求:根据三层架构,搭建web项目
① 创建web项目

② 导入第三方jar包

③ 导入页面资源

④ 搭建三层包目录结构

⑤ 导入 User实体类

⑥ 导入DataUtils工具类(模拟数据库)


⑦ 启动测试

2.2 用户查询功能
需求
使用三层架构和MVC模式开发代码,完成用户显示列表功能。
2.2.1 需求分析

2.2.2 代码实现
① index.jsp

② EncodeFilter
@WebFilter("/*")
public class EncodeFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException {
// 向下转型
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 如果是post请求,解决中文乱码
if (request.getMethod().equalsIgnoreCase("post")) {
request.setCharacterEncoding("utf-8");
}
// 放行
chain.doFilter(request, response);
}
public void destroy() {
}
}
③ FindAllServlet
@WebServlet("/FindAllServlet")
public class FindAllServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.调用service查询
UserService userService = new UserService();
List<User> list = userService.findAll();
// 2.将list存储到request域
request.setAttribute("list", list);
// 3.转发到list.jsp
request.getRequestDispatcher("/list.jsp").forward(request, response);
}
}
④ UserService
public class UserService {
public List<User> findAll() {
// 调用dao查询
UserDao userDao = new UserDao();
// List<User> list = userDao.findAll();
return userDao.findAll();
}
}
⑤ UserDao
public class UserDao {
public List<User> findAll() {
// 调用数据库查询
List<User> list = DataUtils.readAll();
return list;
}
}
⑥ list.jsp
<c:forEach items="${list}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.sex}</td>
<td>${user.age}</td>
<td>${user.address}</td>
<td>${user.qq}</td>
<td>${user.email}</td>
<td>
<a class="btn btn-default btn-sm" href="update.jsp">修改</a>
<a class="btn btn-default btn-sm" href="">删除</a>
</td>
</tr>
</c:forEach>
2.3 添加用户功能
需求
点击添加用户跳转添加用户页面,在添加用户页面,添加新的用户
2.3.1 需求分析

2.3.2 代码实现
① add.jsp

② AddServlet
@WebServlet("/AddServlet")
public class AddServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 1.接收请求参数 map
Map<String, String[]> parameterMap = request.getParameterMap();
// 2.快速封装user实体
User user = new User();
BeanUtils.populate(user, parameterMap);
// 3.调用service,添加user
UserService userService = new UserService();
userService.add(user);
// 4.重定向FindAllServlet
response.sendRedirect(request.getContextPath() + "/FindAllServlet");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
③ UserService

④ UserDao

2.4 删除用户功能
需求
点击删除按钮删除当前一整行数据,删除之后重新查询全部展示删除效果
2.4.1 需求分析

2.4.2 代码实现
① list.jsp

② DeleteServlet

③ UserService

④ UserDao

2.5 修改用户功能
2.5.1 用户回显
需求
点击”修改“按钮,跳转到更新页面(回显数据)
2.5.1.1 需求分析

2.5.1.2 代码实现
① list.jsp

② FindByIdServlet

③ UserService

④ UserDao

⑤ update.jsp

2.5.2 修改用户
需求
重写输入用户信息,点击提交,更新系统
2.5.2.1 需求分析

2.5.2.2 代码实现
① update.jsp

② UpdateServlet
@WebServlet("/UpdateServlet")
public class UpdateServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 1.接收请求参数
Map<String, String[]> parameterMap = request.getParameterMap();
// 2.快速封装到user实体
User newUser = new User();
BeanUtils.populate(newUser, parameterMap);
// 3.调用service,更新
UserService userService = new UserService();
userService.update(newUser);
// 4.重定向,FindAllServlet
response.sendRedirect(request.getContextPath()+"/FindAllServlet");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
③ UserService

④ UserDao
public class UserDao {
// .... 上面方法略...
public void update(User newUser) {
// 1.查询所有
List<User> list = DataUtils.readAll();
// 2遍历
for (User user : list) {
// 判断id是否一致
if (user.getId().equalsIgnoreCase(newUser.getId())) {
try {
// 3.新的数据,覆盖旧的
/* user.setName(newUser.getName());
user.setAge(newUser.getAge());*/
BeanUtils.copyProperties(user, newUser);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
// 4.覆盖原有的数据库
DataUtils.writeAll(list);
}
}
三 优化:Servlet
现在写代码遇到的问题:

优化解决这个问题

了解如何修改?等到数据库阶段学完,还有一个综合案例,练习这种方案...
@WebServlet("/user")
public class UserServlet extends HttpServlet {
// 请求入口
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 判断请求action
String action = request.getParameter("action");
if (action.equals("findAll")) {
this.findAll(request, response);
} else if (action.equals("add")) {
this.add(request, response);
}
}
UserService userService = new UserService();
// 查询所有
protected void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.调用service查询
List<User> list = userService.findAll();
// 2.将list存储到request域
request.setAttribute("list", list);
// 3.转发到list.jsp
request.getRequestDispatcher("/list.jsp").forward(request, response);
}
// 新增
protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 1.接收请求参数 map
Map<String, String[]> parameterMap = request.getParameterMap();
// 2.快速封装user实体
User user = new User();
BeanUtils.populate(user, parameterMap);
// 3.调用service,添加user
userService.add(user);
// 4.重定向FindAllServlet
response.sendRedirect(request.getContextPath() + "/FindAllServlet");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
网友评论