过滤器&监听器

过滤器

1.1.介绍

  • 过滤器是Javaweb的组件,过滤请求和处理响应
  • 使用场景:设置请求/响应字符编码,校验登录权限,敏感单词的过滤
  • 过滤器的声明周期,构造 初始化 过滤 销毁

1.2. filter的使用(xml配置)

1.声明一个过滤器类要实现Filter接口

public class CusFilter implements Filter {
    public CusFilter() {
        System.out.println("filter 构造了");
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter 初始化了");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤请求了!!!");
        //给请求放行 请求真正的资源/或者到下一个过滤器
        filterChain.doFilter(servletRequest, servletResponse);
    }
    @Override
    public void destroy() {
        System.out.println("销毁了");
    }
}

2.doFilter()方法讲解,注意要给请求放行

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤请求了!!!");
        //给请求放行 请求真正的资源/或者到下一个过滤器
        filterChain.doFilter(servletRequest, servletResponse);
    }

3.过滤器的声明周期

  • 构造和初始化是在应用部署好后就执行的而不是第一次访问,而且是只执行一次

  • 过滤方法是每次指定的请求发送过来的时候执行

  • 销毁方法是应用卸载或者TOMCAT关闭的时候执行

4.过滤器的拦截路径写法

  • 精准路径匹配 /ajaSearch.html ,/cart

  • 后缀名匹配 *.html 不要加正斜杠

  • 目录匹配 /html/* 拦截html目录下面的所有资源请求

  • /* 过滤所有请求

        <filter-mapping>
            <filter-name>filter1</filter-name>
            <!--       /* 表示过滤所有请求  -->
            <url-pattern>/*</url-pattern>
            <!--精确路径过滤-->
            <url-pattern>/ajaSearch.html</url-pattern>
            <!--后缀名匹配过滤-->
            <url-pattern>*.html</url-pattern>
            <!--目录匹配过滤-->
            <url-pattern>/html/*</url-pattern>
        </filter-mapping>
    

5.多个过滤器的过滤顺序

​ 拦截顺序与web.xml的配置顺序由关系,配置在上面的先拦截

​ 多个过滤器 A B C

​ 请求拦截 A->B-C 响应顺序 C->B->A (结合生活案例:坐地铁)

6.xml的配置

  <filter>
        <filter-name>filter1</filter-name>
        <filter-class>com.qy28.sm.filter.CusFilter1</filter-class>
        <init-param>
            <param-name>jdbcurl</param-name>
            <param-value>cccc</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>filter1</filter-name>
        <!--       /* 表示过滤所有请求  -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <filter>
        <filter-name>filter2</filter-name>
        <filter-class>com.qy28.sm.filter.CusFilter2</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter2</filter-name>
        <!--       /* 表示过滤所有请求  -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

7.案例,使用filter处理乱码

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestURI = request.getRequestURI();
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/json;charset=UTF-8");
        System.out.println("过滤请求了!!!" + requestURI);
        //doFilter方法表示给请求放行 请求真正的资源/或者到下一个过滤器
        filterChain.doFilter(servletRequest, servletResponse);
    }

1.3. FilterConfig配置类

  • 每个filter都有一个配置类
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取filter的初始化参数
        String jdbcurl = filterConfig.getInitParameter("jdbcurl");
        System.out.println(jdbcurl);
        // 获取上下文对象
        ServletContext servletContext = filterConfig.getServletContext();
        System.out.println("filter 初始化了");
    }

1.4. filter的使用(注解形式)

1.声明filter类

多个过滤器是根据过滤器的名字做自然排序进行拦截

@WebFilter("/*")
public class CusFilter2 implements Filter {}

2.案例,使用filter进行权限校验

前端登录页面

<body>
<form action="/auth">
    user <input type="text" name="username"> <br>
    pass <input type="password" name="password"> <br>
    <input type="submit" value="登录">
</form>
</body>

后端权限校验servlet

@WebServlet("/auth")
public class AuthServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if ("tom".equals(username) && "666".equals(password)) {
            //验证成功后往session域中存放登录信息
            HttpSession session = req.getSession();
            session.setAttribute("user", new User(username, password));
            //
            resp.sendRedirect("/index.html");
        } else {
            resp.sendRedirect("/login.html");
        }
    }
}

后端过滤器

@WebFilter("/*")
public class CusFilter2 implements Filter {
    public CusFilter2() {
        System.out.println("filter2 构造了");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter2 初始化了");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestURI = request.getRequestURI();
        // .css  .js login.html  index.html  .img .jpg /auth
        //正则表达式
//        requestURI.matches("");
        Pattern compile = Pattern.compile(".*(css|js|login.html|index.html|img|jpg|auth)$");
        Matcher matcher = compile.matcher(requestURI);
        if (matcher.matches()) {
            //放行
            filterChain.doFilter(request, response);
        } else {
            HttpSession session = request.getSession();
            Object user = session.getAttribute("user");
            if (user == null) {
                response.sendRedirect("/login.html");
            } else {
                //doFilter方法表示给请求放行 请求真正的资源/或者到下一个过滤器
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

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

监听器 listen

1.1.简介

  • 监听器也是Java web的一个组件,监听域对象(request session 上下文对象)的创建和销毁,以及域对象属性的新增 修改 删除

  • 作用是:是事件发生前和发生后做一些处理

  • 使用场景 统计访问量 统计在线人数 系统初始化动作(数据库连接池的初始化)、

  • 监听域对象的接口

    • ServletRequestListener request域对象的创建和销毁
    • HttpSessionListener session域对象的创建和销毁
    • ServletContextListener ServletContext域对象的创建和销毁
  • 监听域对象属性的接口

    • ServletRequestAttributeListener
    • HttpSessionAttributeListener
    • ServletContextAttributeListener

1.2.使用案例

1.通过监听request域对象统计网站访问量

前端jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
当前网站的访问量是 : ${requestScope.count}
</body>
</html>

后端监听器代码,监听器和过滤器以及servlet一样都是单例的

public class CusRequestListener implements ServletRequestListener {
    //多线程环境下使用线程安全的类,原子性
    private AtomicInteger count = new AtomicInteger(0);

    public CusRequestListener() {
        System.out.println("request监听器实例化的!!!");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        count.incrementAndGet();
        servletRequestEvent.getServletRequest().setAttribute("count", count);
        System.out.println("创建了一个 request对象");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
    }
}

1.3. 三大组件的启动顺序

servlet filter listener

监听器先启动 过滤器启动 servlet启动

都是单例的,只有一个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值