美文网首页
4/25day41_listener

4/25day41_listener

作者: 蹦蹦跶跶的起床啊 | 来源:发表于2020-05-15 21:36 被阅读0次

回顾

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包

③ 导入页面资源

④ 搭建三层包目录结构

1587782022814.png

⑤ 导入 User实体类

1587782097855.png

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

1587782181537.png 1587782209409.png

⑦ 启动测试

1587782430403.png

2.2 用户查询功能

需求

使用三层架构和MVC模式开发代码,完成用户显示列表功能。

2.2.1 需求分析

1587782969066.png

2.2.2 代码实现

① index.jsp

1587783085177.png

② 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>
            &nbsp;<a class="btn btn-default btn-sm" href="">删除</a>
        </td>
    </tr>
</c:forEach>

2.3 添加用户功能

需求

点击添加用户跳转添加用户页面,在添加用户页面,添加新的用户

2.3.1 需求分析

1587785285009.png

2.3.2 代码实现

① add.jsp

1587785388952.png

② 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

1587786208128.png

④ UserDao

1587786228205.png

2.4 删除用户功能

需求

点击删除按钮删除当前一整行数据,删除之后重新查询全部展示删除效果

2.4.1 需求分析

1587786860427.png

2.4.2 代码实现

① list.jsp

1587787042487.png

② DeleteServlet

1587787437317.png

③ UserService

1587787454818.png

④ UserDao

1587787484267.png

2.5 修改用户功能

2.5.1 用户回显

需求

点击”修改“按钮,跳转到更新页面(回显数据)

2.5.1.1 需求分析

1587795243681.png

2.5.1.2 代码实现

① list.jsp
1587795752834.png
② FindByIdServlet
1587796218744.png
③ UserService
1587796232347.png
④ UserDao
1587796263253.png
⑤ update.jsp
1587796315291.png

2.5.2 修改用户

需求

重写输入用户信息,点击提交,更新系统

2.5.2.1 需求分析

1587796792807.png

2.5.2.2 代码实现

① update.jsp
1587796936278.png
② 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
1587797730474.png
④ 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

现在写代码遇到的问题:

1587798105877.png

优化解决这个问题

1587798494835.png

了解如何修改?等到数据库阶段学完,还有一个综合案例,练习这种方案...

@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();
        }
    }
}

相关文章

  • 4/25day41_listener

    回顾 Listener&综合案例 今日目标 一 Listener【了解】 1.1 概述 生活中的监听器 我们很多商...

  • 4/4

    已完成 原本想听写一首歌,实在太懒 要改要克服 目标: 1.瘦10斤 2.赚10w 3.学英语and韩语

  • 4/4

    一大早就发现今天的天气冷,一出门冷傻了,其实冷点没什么,关键是在路上要资源,没一人理你。

  • 4/4

    在適合吃糖的年紀,吃苦在適合跳舞的時光,匆匆在適合終老的睡眠,清醒在沒有兒童的節日,兒童在十四歲以前就安葬年輕,沈...

  • 4/4

    第五十六回 曹操大宴铜雀台 孔明三气周公瑾 曹操一直想报赤壁之仇,奈何孙刘联合一直按兵不动,金碧辉煌的铜雀台已竣工...

  • 4—4

    新员工切配考试。

  • 4!4!

    如果找不到一个兴趣爱好重叠的人,那找个能够支持你的也是好的哇

  • 4/4

    点了一杯咖啡,从季风书园挑了三本书,一坐就是一下午。难得拥有这么闲瑕的时光,静静翻阅着书籍,闻着纸墨的芳香,感...

  • 4/4

    7:39我在43路车上了 今天居然这么早 我已经带着饭了 应该会感动死她哦嘻嘻 jx和L两个魔鬼吗 昨天学习通宵 ...

  • 4/4

    无花无酒过清明,兴味萧然似野僧。------《清明感事》王禹偁 我是在无花可观赏,无酒可饮的情况下过这个清明节的,...

网友评论

      本文标题:4/25day41_listener

      本文链接:https://www.haomeiwen.com/subject/ihnhohtx.html