javaweb--过滤器、监听器

过滤器 Filter (重点)

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

  • 过滤器中的所有代码,在过滤特定的请求时候都会执行

  • 必须要让过滤器继续同行 :

  chain.doFilter(request,response);

过滤器的作用 :

  • 过滤中文乱码
  • 登陆验证

在这里插入图片描述

需要用到的依赖

<!--servlet-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>
<!--jsp-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
</dependency>
<!-- jstl -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<!-- standard -->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

实现 Filter 的步骤

1、编写 filter :

注意 :导包不要导错

在这里插入图片描述

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

public class CharacterEncodingFilter implements Filter {
    /**
     *初始化
     * web 服务器启动的时候,就已经初始化了,随时等待过滤对象出现
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("开始初始化");
    }

    /**
     * 过滤器中的所有代码,在过滤特定的请求时候都会执行
     * 必须要让过滤器继续同行 : chain.doFilter(request,response);
     * @param request
     * @param response
     * @param chain   链
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        response.setCharacterEncoding("utf-8");
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        System.out.println("执行前");
        //让我们的请求继续往前走,如果不写,程序到这里就会被拦截停止
        chain.doFilter(request,response);
        System.out.println("执行后");
    }

    /**
     * 销毁
     * web 服务器关闭时,过滤自动销毁
     */
    @Override
    public void destroy() {
        System.out.println("开始销毁");
    }
}

2、编写 servlt

什么都不写,这样输出到页面肯定是乱码,我们在web.xml 中配置两个映射路径,一个通过过滤器,一个不通过过滤器,我们来对比一下

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("你好,世界!!!");
}

3、配置 web.xml

<?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_4_0.xsd"
         version="4.0"
         metadata-complete="true">

    <servlet>
        <servlet-name>respDemo</servlet-name>
        <servlet-class>com.hkp.servlet.RespDemo</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>respDemo</servlet-name>
        <url-pattern>/servlet/show</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>respDemo</servlet-name>
        <url-pattern>/show</url-pattern>
    </servlet-mapping>

    <!--  格式与servlet的类似  -->
    <!--这样设置的话,方式请求中以 /servlet 或 /sys 开头的请求都会走过滤-->
    <filter>
        <filter-name>characterEncoding</filter-name>
        <filter-class>com.hkp.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>characterEncoding</filter-name>
        <!--设置需要过滤的请求-->
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>characterEncoding</filter-name>
        <!--设置需要过滤的请求-->
        <url-pattern>/sys/*</url-pattern>
    </filter-mapping>

</web-app>

4、启动测试

通过过滤器的测试

在这里插入图片描述

没有通过过滤器的测试
在这里插入图片描述

实现登陆过滤

用户登陆后就可以进入主页,退出后就不能进入主页

1、准备三个 jsp 页面 login.jsp success.jsp failure.jsp

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/servlet/login">
    用户名 :<input type="text" name="username"/>
    密码 :<input type="password" name="password"/>
    <input type="submit">
</form>
</body>
</html>

success.jsp

注意 :这个jsp页面我们给他在webapp文件夹下创建一个文件夹,主要用于方便过滤

<%--
  Created by IntelliJ IDEA.
  User: han11
  Date: 2021/8/31
  Time: 14:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>${USER_SESSION}</h1>
<h1>欢迎<%=session.getAttribute("USER_SESSION")%>,登陆成功!!!</h1>
<h1><a href="${pageContext.request.contextPath}/servlet/logout">注销</a></h1>
</body>
</html>

failure.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>用户名或密码错误</h1>
<h1><a href="${pageContext.request.contextPath}/login.jsp">返回登陆页面</a></h1>
</body>
</html>

2、编写 servlet

LoginServlet

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取用户请求过来的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //判断用户信息是否正确
        if(username.equals("root")&&password.equals("admin")){//登陆成功
            //获取session
            HttpSession session = req.getSession();
            //将用户浏览器中的SessionID存入session中
            session.setAttribute("USER_SESSION",session.getId());
            //重定向 成功页面  filter 为项目名
            resp.sendRedirect("/filter/sys/success.jsp");
        }else{//登陆失败
            //重定向 失败页面 filter 为项目名
            resp.sendRedirect("/filter/failure.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

LogoutServlet

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

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取 session
        HttpSession session = req.getSession();
        Object user_session = session.getAttribute("USER_SESSION");
        if(user_session!=null){//登录
            //移除session
            session.removeAttribute("USER_SESSION");
            // 重定向到登陆页面 filter 为项目名
            resp.sendRedirect("/filter/login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3、编写 过滤器

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

public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //由于我们的session 是HttpServletRequest 中的,所以我们要对 request 对象进行强转
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        //由于 重定向需要的是 HttpServletResponse 中的sendRedirect方法,所以需要强转一下
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        //获取session
        HttpSession session = req.getSession();
        Object user_session = session.getAttribute("USER_SESSION");
        if(user_session==null){//未登录
            // filter 为项目名
            resp.sendRedirect("/filter/login.jsp");
        }
        //注意 :这里不能再写 else 然后重定向到 成功页面了,因为我们在 LoginServlet 中已经将重定向过一次了,
        // 在这里如果在写的话就会因重定向次数过多而访问不到
        
        //保证 过滤器正常继续执行下去
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

4、配置web.xml

<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.hkp.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <!--设置需要过滤的请求-->
    <url-pattern>/sys/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>login</servlet-name>
    <servlet-class>com.hkp.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>logout</servlet-name>
    <servlet-class>com.hkp.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>logout</servlet-name>
    <url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>

5、测试

  • 启动项目 (项目的访问项目名称为 filter,路径为 http://localhost :8080/filter/index.jsp)
  • 访问登陆页面
  • 输入错误的用户信息,使其跳转到错误页面
  • 点击错误页面的返回登陆页面
  • 输入正确的用户信息,使其跳转到成功页面
  • 点击成功页面的注销按钮
  • 直接访问成功页面 http://localhost :8080/filter/sys/success.jsp 看过滤器是否生效

监听器

统计网站在线人数

1、编写 servlet

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
 * 统计在线人数
 * 统计session
 */
public class OnlineCountListener implements HttpSessionListener {
    /**
     * 创建session 监听
     * 一旦创建session就会触发这个事件
     *
     * @param se
     */
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        Integer count = (Integer) context.getAttribute("OnlineCount");

        if (count == null) {
            //如果在线人数为null,在线人数为1
            count = 1;
        } else {
            //如果在线人数不为null,在线人数加1
            count++;
        }
        context.setAttribute("OnlineCount", count);
    }

    /**
     * 销毁session监听
     * 一旦销毁session就会触发这个事件
     *
     * @param se
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        Integer count = (Integer) context.getAttribute("OnlineCount");

        if (count == null) {
            //如果在线人数为null,在线人数为1
            count = 0;
        } else {
            //如果在线人数不为null,在线人数加1
            count--;
        }
        context.setAttribute("OnlineCount", count);
    }
}

2、编写 jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--两种方式都可以取到值--%>
${OnlineCount}
<h1>当前有<span><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人在线</h1>
</body>
</html>

3、配置 web.xml

<!--注册监听器-->
<listener>
    <listener-class>com.hkp.listener.OnlineCountListener</listener-class>
</listener>

4、测试

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值