JavaWeb阶段(Filter和Listener的详情介绍)

Filter

当用户访问服务器资源时,过滤器将请求拦截下来,完成一些通用的操作。

快速入门之.xml配置实现

编写java类,实现Filter接口

/**
 * @author lifly
 * @date 2021/6/20 0020 20:49
 */
public class QuickFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    /**
     * 该方法拦截用户请求
     * @param servletRequest    请求对象
     * @param servletResponse   响应过滤
     * @param filterChain       过滤器链(是否放行)
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("quickFilter拦截了请求。。。");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

web.xml配置

<!--    快速入门-->
<!--    注册filter-->
    <filter>
        <filter-name>QuickFilter</filter-name>
        <filter-class>com.lifly.filter.QuickFilter</filter-class>
    </filter>
<!--    配置filter拦截路径-->
    <filter-mapping>
        <filter-name>QuickFilter</filter-name>
        <url-pattern>/quick.jsp</url-pattern>
    </filter-mapping>

快速入门之注解实现

/**
 * @author lifly
 * @date 2021/6/20 0020 20:58
 */
//@WebFilter("/annotationFilter.jsp")//精准匹配
//@WebFilter("/filter/*")//目录匹配
//@WebFilter("*.html")//后缀匹配
@WebFilter("/*")//匹配所有
public class AnnotationFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("注解配置过滤器");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

Filter的声明周期

init服务器启动项目加载,创建filter,执行init方法(只执行一次)
doFilter用户访问被拦截目标资源时,执行doFilter方法,执行多次
destory服务器关闭前,Filter对象被销毁。如果服务器是正常关闭,则会执行destory方法,只执行一次。
过滤器一定是优先于Servlet创建的

拦截路径

  1. 精准匹配
    用户访问制定目标资源例如(/index.jsp)时,过滤器进行拦截
  2. 目录匹配
    用户访问指定目录下例如(/user/*)所有资源时,过滤器进行拦截
  3. 后缀匹配
    用户访问指定后缀名(.html)的资源时,过滤器进行拦截
    4.匹配所有
    用户访问该网站所有资源(/
    )时,过滤器进行拦截
//@WebFilter("/annotationFilter.jsp")//精准匹配
//@WebFilter("/filter/*")//目录匹配
//@WebFilter("*.html")//后缀匹配
@WebFilter("/*")//匹配所有

过滤器链

在一次请求中,请求匹配到多个filter,通过请求就相当于把这些filter串起来,形成了过滤器连

需求

用户访问目标路径show.jsp时,经过FilterA,FilterB
过滤器执行链执行顺序(先进后出)

  1. 用户发送请求
  2. FilterA拦截,放行
  3. FilterB拦截,放行
  4. 执行目标资源show.jsp
  5. FilterB增强响应
  6. FilterA增强响应
  7. 封装响应响应格式,返回到浏览器

代码演示

  1. show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3>过滤器链</h3>
</body>
</html>

  1. FilterA.java
/**
 * @Describe
 * @Author Double LiFly
 * @date 2021/6/21 10:18
 */
@WebFilter("/show.jsp")
public class FilterA implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterA拦截。。。");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("filterA放行");
    }

    @Override
    public void destroy() {

    }
}

  1. FilterB.java
/**
 * @Describe
 * @Author Double LiFly
 * @date 2021/6/21 10:19
 */
@WebFilter("/show.jsp")
public class FilterB implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterB拦截。。。");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("filterB放行");
    }

    @Override
    public void destroy() {

    }
}

Listener

在java程序中,有时候需要监视某些事情,一旦被监视的对象发生相应的变化,执行相应的操作。
例如:使用于历史访问次数,统计在线人数,系统启动初始化配置信息

作用

  1. 监听作用域对象的创建和销毁
    ServletRequestListener:监听请求对象的创建和销毁
    HttpSessionListener:监听会话对象(session)的创建和销毁
    ServletContextListener:监听应用的创建和销毁
  2. 监听作用域对象的属性的添加,删除,替换

快速实现

实现步骤

定义一个类,实现ServletContextListener接口
重写接口中的抽象方法
配置监听器

实现

/**
 * @Describe
 * @Author Double LiFly
 * @date 2021/6/21 14:07
 */
public class ListenerDemo01 implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContextListener创建了");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContextListener销毁了");
    }
}
//监听器配置
    <listener>
        <listener-class>com.lifly.listener.ListenerDemo01</listener-class>
    </listener>

统计网站在线人数

有用户使用网站,在线人数就+1;用户退出在线人数就减1

代码演示
  1. index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    在线人数: ${number}
    <br>
    <a href="/logoutServlet">退出系统</a>
  </body>
</html>
  1. InitNumberListener.java
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    在线人数: ${number}
    <br>
    <a href="/logoutServlet">退出系统</a>
  </body>
</html>
  1. NumberChangeListener.java
/**
 * @Describe
 * @Author Double LiFly
 * @date 2021/6/21 14:12
 */
@WebListener
public class NumberChangeListener implements HttpSessionListener {
    /**
     * session创建
     * @param httpSessionEvent
     */
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
        int number = (int) servletContext.getAttribute("number");
        servletContext.setAttribute("number",number+1);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
        int number = (int) servletContext.getAttribute("number");
        servletContext.setAttribute("number",number-1);
    }
}
  1. logoutServlet.java
@WebServlet("/logoutServlet")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理post请求乱码问题
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //销毁
        request.getSession().invalidate();

    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_lifly

点喜欢就是最好的打赏!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值