欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Servlet笔记 —— JavaWeb三大组件 Servlet,Filter,Listener

程序员文章站 2024-02-09 15:53:34
...

JavaWeb三大组件

Servlet(前面已经说过)

Filter

概念

当访问服务器资源时,过滤器可以对请求进行拦截,并完成一些特殊的功能。比如可以用过滤器来对请求统一设置编码,进行登录验证,过滤敏感词汇等。过滤器一般用来完成一些通用的功能

快速入门

编写Filter的步骤

  1. 定义一个类,实现Filter接口

  2. 重写接口的方法

  3. 配置Filter(主要是配置拦截路径,比如/*会拦截所有请求)

    1. web.xml配置
    2. 注解配置 @WebFilter
  4. 代码实现

    public class LogFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init...");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) servletRequest; 
            System.out.println("Calling -> " + request.getRequestURL());
            //放行
            filterChain.doFilter(servletRequest,servletResponse);
            System.out.println("Finished -> " + request.getRequestURL());
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy...");
        }
    }
    
Filter的细节
  1. Filter的执行流程(类似于AOP)

  2. Filter的生命周期

    1. init():服务器启动后,创建Filter对象,调用init,只执行一次
    2. doFilter():每次请求被拦截时,执行doFilter,会执行多次
    3. destroy():服务器正常关闭,调用destroy,销毁Filter对象,只执行一次
  3. 配置详解

    1. 拦截路径配置

      1. /index.jsp 拦截具体资源
      2. /login/* 拦截某一类资源
      3. *.jsp 拦截某一类
      4. /* 拦截所有
      	<filter>
              <filter-name>logFilter</filter-name>
              <filter-class>com.yogurt.filter.LogFilter</filter-class>
          </filter>
          
          <filter-mapping>
              <filter-name>logFilter</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>
      
    2. 拦截方式配置

      1. 方式指的是,资源被访问的方式,比如浏览器直接请求访问,或者服务器转发访问。指定了该参数,则Filter只会在满足url-pattern,且请求方式满足该参数指定值,才会执行拦截。

      2. 设置dispatcherType属性即可

        1. REQUEST 浏览器直接请求访问(默认值)
        2. FORWARD 服务器转发访问时
        3. INCLUDE 包含访问
        4. ERROR 错误跳转资源
        5. ASYNC 异步访问资源
      3. web.xml配置

        	<filter-mapping>
                <filter-name>logFilter</filter-name>
                <url-pattern>/*</url-pattern>
                <dispatcher>REQUEST</dispatcher>
            </filter-mapping>
        
      4. 注解配置

        @WebFilter(urlPatterns = "/*",dispatcherTypes = DispatcherType.FORWARD)
        
        package javax.servlet;
        public enum DispatcherType {
            FORWARD,
            INCLUDE,
            REQUEST,
            ASYNC,
            ERROR;
            private DispatcherType() {
            }
        }
        
  4. 过滤器链

    可以配置多个过滤器,各个过滤器链式执行。测试发现Filter初始化是按照Filter的名称的字典顺序进行初始化的,不管是web.xml配置还是注解配置,web.xml配置的话,不管<filter>标签的位置。

    1. 执行顺序

      1. 注解配置:

        默认是按照过滤器名称的字符串顺序来先后执行各个过滤器

        如有2个Filter,AFilter和BFilter,则AFilter先执行,BFilter后执行

      2. web.xml配置:

        <filter-mapping>标签在前面的Filter先执行,配置在后面的后执行

        示例

        	<!-- 则会先执行cidFilter -->
        	<filter-mapping>
                <filter-name>cidFilter</filter-name>
                <url-pattern>/*</url-pattern>
            </filter-mapping>
        
            <filter-mapping>
                <filter-name>logFilter</filter-name>
                <url-pattern>/*</url-pattern>
            </filter-mapping>
        
Filter的案例
  1. 登录验证(权限控制框架的最基本的内容)

    Filter中验证session是否包含user信息,若包含,说明用户已登录,放行;否则,提示用户未登录,并跳转到登录页面。

    注意:配置Filter的拦截路径时,可能需要注意对静态资源也放行。

    思路:

    • 判断是否是登录相关的资源

      • 是。则直接放行。(比如请求登录页面,本身就是要做登录操作,故不作拦截)

        (注意,对静态资源,如css/js/验证码等资源也需要进行放行。否则页面会不正常)

      • 否,进行拦截,判断用户是否已登录

    • 判断用户是否已登录(通过session中的数据来判断)

      • 是。则放行
      • 否,没有登录,则跳转到登录页面,提示用户进行登录,用户登录完成后,会将登录用户的信息存在session中
  2. 敏感词过滤

    1. 敏感词数据表
    2. 如果请求入参中有敏感词汇,替换为***
    3. 因为request只有个getParameter用来获取请求参数,却没有setParameter这样的方法用来修改请求中的参数,所以需要对request对象的getParameter方法进行增强(AOP),产生一个新的request对象,传递下去

    需要对request对象进行增强,可以使用JDK动态代理

Listener

  1. 概念:事件监听器

  2. 事件监听机制

    1. 事件:一件事情,比如点击事件
    2. 事件源:事件发生的地方
    3. 监听器:一个对象
    4. 注册监听:将事件,事件源,监听器,绑定在一起。当在事件源上发生了某个事件,则执行监听器代码
  3. ServletContextListener

    1. 包含方法

      void contextInitialized(ServletContextEvent sce)

      在ServletContext对象被创建后,调用该方法

      void contextDestroyed(ServletContextEvent sce)

      在ServletContext对象被销毁前,调用该方法

    2. 实现一个Listener来监听Servlet的步骤

      1. 定义一个类,实现ServletContextListener接口

        @WebListener
        public class YogurtListener implements ServletContextListener {
        	@Override
        	public void contextInitialized(ServletContextEvent sce) {
        		//可以加载一些初始资源
        		ServletContext servletContext = sce.getServletContext();
        		String location = servletContext.getInitParameter("location");
        		System.out.println(location);
        		System.out.println("启动拉");
        	}
        
        	@Override
        	public void contextDestroyed(ServletContextEvent servletContextEvent) {
        
        	}
        }
        
      2. 配置

        1. web.xml配置

          <<listener>
                  <listener-class>com.yogurt.listener.YogurtListener</listener-class>
              </listener>
          

          可以在web.xml中配置contextParam,然后监听Servlet启动时,获取这些参数,实现Servlet启动时加载一些资源(先前手写Spring时,就是利用这种方式,进行Spring容器的初始化的)

          <context-param>
                  <param-name>location</param-name>
                  <param-value>classpath:yogurt.properties</param-value>
              </context-param>
          
        2. 注解配置

          在Listener的类上直接加注解@WebListener即可

相关标签: Web web servlet