怀旧网,博客详情:Filter过滤器、监听器 介绍

1、Java Web 的基本概念

2、IDEA 中配置启动Tomcat

3、如何运行第一个Tomcat HttpServlet 程序

4、Servlet 详解

5、Response 和 Request 介绍

6、Cookie Session 介绍

7、JSP 详细讲解

8、Java Bean 介绍

9、MVC 架构介绍

10、Filter过滤器、监听器 介绍

11、JDBC 事务的使用

12、Java Web 文件上传

原创

Filter过滤器、监听器 介绍

过滤器

Filter:过滤器用来过滤网站的数据;

  • 处理中文乱码
  • 登录验证...

image-20240331201523684

过滤器实现步骤:

创建一个类实现Filter接口

注意:Fliter 是 javax.servlet 包下面的;

import javax.servlet.*;
import java.io.IOException;

public class FilterTest implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化了...");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 默认让请求继续往后执行(要是不写所有被拦下的请求都回没有任何反应)
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("过滤器销毁了...");
    }
}

将filter注册(编写xml配置)

<filter>
    <filter-name>filterTest</filter-name>
    <filter-class>com.huaijiuwang.config.FilterTest</filter-class>
</filter>
<filter-mapping>
    <filter-name>filterTest</filter-name>
    <url-pattern>/huaijiu</url-pattern>
</filter-mapping>

使用测试:

使用过滤器解决乱码问题

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.getWriter().println("我是怀旧!");
    }
}
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.huaijiuwang.servlet.HelloServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/huaijiu</url-pattern>
</servlet-mapping>

访问测试:

image-20240331202240871

程序启动就完成了过滤器的初始化

image-20240331202540801

输出乱码

配置过滤器,在启动阶段就设置好响应编码

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    // 配置编码
    servletRequest.setCharacterEncoding("utf-8");
    servletResponse.setCharacterEncoding("utf-8");
    servletResponse.setContentType("text/html;charset=utf-8");

    // 默认让请求继续往后执行(要是不写所有被拦下的请求都回没有任何反应)
    filterChain.doFilter(servletRequest, servletResponse);
}

image-20240331203039324

成功解决乱码问题

image-20240331203111214

当程序退出过滤器才会被销毁...

image-20240331203711066

过滤器在初始化可以获取Context等对象,可以设置一些初始化操作(不建议使用)

监听器

配置监听器还是直接实现一个监听的接口

监听器的更多详细介绍请点击:网页链接

通过监听器实现在线人数统计案例:

编写一个监听器:

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

// 这边想监听那个东西就实现那个东西的监听器接口 HttpSessionListener
public class ListenerTest implements HttpSessionListener {
    // 创建session监听
    public void sessionCreated(HttpSessionEvent se) {
        // 获取当前的session对象
        HttpSession session = se.getSession();

        // 获取servletContext全局对象,用来存储当前用户数量数据(因为servletContext是全局都可以访问的)
        ServletContext servletContext = session.getServletContext();

        // 获取 servletContext 对象中存储当前在线人数的数量
        Integer userCount = (Integer)servletContext.getAttribute("userCount");

        // 判断当前是否为第一个用户
        if(userCount == null){
            // 是第一个session就创建一个对象放入 servletContext 中
            servletContext.setAttribute("userCount", 1);
        }else{
            // 当不是第一个用户的时候,就让用户数量增加
            servletContext.setAttribute("userCount", userCount + 1);
        }

        // 当一个session创建输出一下sessionId
        System.out.println("当前sessionID: " + session.getId());
    }

    // 销毁session监听
    public void sessionDestroyed(HttpSessionEvent se) {
        // 获取当前的session对象
        HttpSession session = se.getSession();

        // 获取servletContext全局对象,用来存储当前用户数量数据(因为servletContext是全局都可以访问的)
        ServletContext servletContext = session.getServletContext();

        // 获取 servletContext 对象中存储当前在线人数的数量
        Integer userCount = (Integer)servletContext.getAttribute("userCount");

        // 让当前存在用户数量减一
        servletContext.setAttribute("userCount", userCount - 1);
    }
}

将监听器注册

<listener>
    <listener-class>com.huaijiuwang.config.ListenerTest</listener-class>
</listener>

编写访问jsp界面

<%@ page import="com.huaijiuwang.model.User" %>
<html>
<head>
</head>
<body>
  <h1>当前在线用户数量为: <%=request.getServletContext().getAttribute("userCount")%></h1>
</body>
</html>

启动运行测试:

image-20240331205939148

发现当前在线用户为3个

image-20240331205951490

session访问一次就创建了3个:

原因是:

  1. 框架或容器内部使用:有些框架或容器可能会在应用启动时创建一些内部会话,用于管理用户登录状态、权限验证等。这些会话对外部用户是不可见的,但对框架或容器的内部运作是必要的。
  2. 测试或初始化:在应用启动时,可能会有一些初始化操作需要创建会话来测试会话管理的有效性,或者为了初始化一些会话相关的数据结构。
  3. 默认会话:某些容器可能会创建一些默认的会话对象,以便在没有明确创建会话的情况下,能够提供一些基本的会话功能。(这一个才是我们本身对象是session)

image-20240331210149819

实际的session就是最后创建这一个

image-20240331210208823

再次刷新网页,session恢复正常,打开另一个浏览器再次测试

image-20240331210244887

用户数量成功增加-现在关闭一个浏览器

image-20240331210307241

用户数量没有减少:

原因是当前会话关闭后,session自动关闭的时间是系统设定了(默认是30分钟后失效),但是我们也可以手动配置session的失效时间:

<session-config>
    <session-timeout>1</session-timeout>
</session-config>

配置一分钟后失效

我们还是打开两个浏览器,然后在关闭一个

image-20240331210618133

现在关闭其中一个浏览器,等待一分钟后刷新:

image-20240331210827756

由于内部问题:具体session销毁时间不太确定,但是大概等了2~3分钟就注销了

过滤器实现用户登录拦截案例

编写一个需要用户登录才能访问的界面

image-20240331210950679

在user文件件下面创建一个admin.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>当前界面为登录后才能访问登录用户为:<%=session.getAttribute("user")%></h1>
</body>
</html>

启动项目

image-20240331211240652

发现可以直接进行访问(现在就需要配置过滤器,拦截 /user 下面的所有请求)

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class UserFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 由于当前的servletRequest对象为ServletRequest对象,获取不到session数据,所以我们先讲数据强转
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // 获取session
        HttpSession session = request.getSession();

        // 获取当前登录用户信息
        Object user = session.getAttribute("user");

        // 判断当前用户是否登录
        if(user == null){
            // 当前用户已经登录,直接放行
            filterChain.doFilter(servletRequest, servletResponse);
        }else{
            // 当前用户未登录,重定向到登录界面去

            // 先将ServletResponse转成HttpServletResponse
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            response.sendRedirect("/login.jsp"); // 
        }
    }
}

将过滤器注册,并配置拦截请求为 /user/* user下的所有请求

<filter>
    <filter-name>userFilter</filter-name>
    <filter-class>com.huaijiuwang.config.UserFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>userFilter</filter-name>
    <url-pattern>/user/*</url-pattern>
</filter-mapping>

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>登录界面</h1>
</body>
</html>

再次访问/user/admin.jsp

image-20240331213323680

访问就直接跳转到了login.jsp界面了

现在添加登录功能

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>登录界面</h1>

    <form action="/login" method="get">
        用户名:<input type="text" name="user" />
        <input type="submit" value="登录" />
    </form>
</body>
</html>

添加登录数据处理请求

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取登录数据
        String user = req.getParameter("user");

        // 判断用户是否可以进行登录
        if("huaijiu".equals(user)){
            // 当输入huaijiu就可以登录

            // 将登录数据放入session
            HttpSession session = req.getSession();
            session.setAttribute("user", user);
            
            // 跳转到登录成功界面
            resp.sendRedirect("/user/admin.jsp");
        }else{
            // 不能成功登录(返回到登录界面)
            resp.sendRedirect("/login.jsp");
        }
    }
}

配置访问映射

<servlet>
    <servlet-name>login</servlet-name>
    <servlet-class>com.huaijiuwang.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

开始测试:

image-20240331213948238

访问/user/admin.jsp自动跳转

测试输入错误用户名

image-20240331214008352

image-20240331214015406

点击登录,重新回到login界面

输入正确用户名测试

image-20240331214210743

访问成功,添加注销功能

在前端添加注销按钮

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>当前界面为登录后才能访问登录用户为:<%=session.getAttribute("user")%></h1><br />
    <a href="/logout">点击注销</a>
</body>
</html>

编写注销servlet

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取session
        HttpSession session = req.getSession();

        // 删除session中的登录对象
        session.removeAttribute("user");

        // 重定向到登录界面
        resp.sendRedirect("/login.jsp");
    }
}

注册注销映射

<servlet>
    <servlet-name>logout</servlet-name>
    <servlet-class>com.huaijiuwang.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>logout</servlet-name>
    <url-pattern>/logout</url-pattern>
</servlet-mapping>

访问测试

image-20240331214607121

先进行登录

image-20240331214612902

点击注销

image-20240331214620708

返回到登录界面了,现在不登录再次访问/user/admin.jsp

image-20240331214640053

访问被拦截了,重定向到了登录界面

  • 平台作者:怀旧(联系作者)
  • QQ:444915368
  • 邮箱:444915368@qq.com
  • 电话:17623747368
  • 评论

    登录后才可以进行评论哦!

    回到顶部 留言