JavaWeb④过滤器、监听器

Java Web 三大组件:Servlet、Filter、Listener

1、过滤器(Filter)

过滤器:客户端与服务器目标资源之间的一道过滤技术。

  • 拦截请求,对客户端请求进行过滤处理。

  • 封装共性代码,避免重复编码(如设置字符编码、登录验证)

    image-20220324222142703

1.1、Filter API

javax.Servlet API 中提供了 Filter 接口

:三个方法都需要重写。

  • init():初始化,在 Filter 开始之前工作前由 web 容器调用。

  • doFilter():将请求和响应传递给链中的下一个实体。

  • destory():销毁。当调用了过滤器的 doFilter() 的所有线程都退出后,由 web 容器调用。

    public interface Filter {
        default public void init(FilterConfig filterConfig) throws ServletException {}
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;
    
        default public void destroy() {}
    }
    

使用

  • 创建:实现 Filter 接口

    1. doFilter() 中编写过滤逻辑
    2. 调用 chain.doFilter() 放行
  • 配置:配置 Filter 的拦截路径(类似 Servlet 有两种方式)

    • 注解@WebFilter

    • web.xml:类似 Servlet 配置,/* 通配

      <filter>
          <filter-name>encodeFilter</filter-name>
          <filter-class>自定义Filter的全限类名</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>encodeFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
      

1.2、过滤路径

Filter 过滤路径有 3 种匹配形式

(相比 Servlet,Filter 不能使用 / 通配符)

匹配顺序:精确匹配 > 后缀匹配 > 通配

含义 说明
/具体URL 精确过滤 过滤 指定 URL
*.xxx 后缀过滤 过滤 xxx 后缀
/* 通配 过滤 任意 URL

1.3、过滤器链、优先级

责任链模式的体现

在客户端和所请求的服务器端资源之间,可能存在多个过滤器。

  • 过滤器和服务器端资源形成一条过滤器链。

  • 多个过滤器之间,通过 FilterChain.doFilter() 传递请求和响应。

    image-20220324222326426

优先级问题

Filter 有两种配置方式:配置文件、注解。

  1. 基于配置文件:按 filter-mapping 的注册顺序从上往下执行
  2. 基于注解:按全限类名的字符串顺序决定顺序。
  3. 配置文件优先级比注解高。
  4. 同时为一个 Filter 进行配置文件和注解配置,则会注册多个过滤器对象,过滤多次。

1.4、应用

1.4.1、编码问题

回顾:Servlet-3.3 请求 & 响应

抽取 Servlet 中处理请求(响应)编码的逻辑。

@WebFilter("/*")
public class EncodeFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        chain.doFilter(request, response);
    }

    // init()、destory()
}

1.4.2、用户认证

回顾:状态管理-1.2.4

抽取 Servlet 中判断 Session 的逻辑。

注意

  1. 向下转型

    • doFilter() 中的请求和响应是 ServletRequestServletResponse
    • 我们使用是 HttpServletRequestHttpServletResponseHttpSession
  2. 过滤路径:将涉及用户操作的页面进行拦截,尤其注意不能拦截登录页(否则登录也会被拦截)。

    @WebServlet("/user/*")
    public class AuthenticationFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            // 向下转型
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse resp = (HttpServletResponse) response;
            // 判断
            HttpSession session = req.getSession();
            User user = (User) session.getAttribute("user");
            if (user == null) {
                resp.sendRedirect("/");
            }
            // 放行
            chain.doFilter(req, resp);
        }
        // init()、destory()
    }
    

2、监听器(Listener)

观察者模式 的体现

监听器:监听对象的技术

  • 作用:监听对象的创建和销毁、元素的增删改,自动执行相应功能。
  • 监听对象applicationsessionrequest

2.1、Listener API

javax.Servlet API 中提供了 Listener 接口

共有以下 8 种

image-20220324222827345

2.2、配置

Listener 的 2 种配置方式

  1. XML 配置

    <listener>
        <listener-class>监听器类</listener-class>
    </listener>
    
  2. 注解@WebListener

2.3、使用

以 ServletContextListener 为例,演示监听器

实现 ServletContextListener 接口

  • contextInitialized():ServletContext 对象创建时自动执行

  • contextDestroyed()ServletContext 对象销毁时自动执行

  • 方法参数:被监听的事件。

    @WebListener
    public class MyListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("Initializing...");
        }
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("Destroying...");
        }
    }
    

测试:启动 Tomcat 服务器

ServletContext 对应一个 Web 应用,Tomcat 服务器启动时创建,服务器关闭时销毁。

image-20220324224456766

posted @ 2021-06-29 22:38  Jaywee  阅读(77)  评论(0编辑  收藏  举报

👇