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

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即可

猜你喜欢

转载自blog.csdn.net/vcj1009784814/article/details/106107400