Filter和Listener

servlet+filter+listener被称为javaweb的三大组件

Filter(重要)

  1. Filter: 过滤器

    • 生活中的过滤器: 如生活中的净水器,空气净化器等都是过滤器.
    • web中的过滤器: 当浏览器通过请求访问服务器资源时,过滤器可以将请求拦截下来,来完成一些特殊的功能.
  2. 过滤器的作用

    • 一般用于完成通用的操作.
      • 登录验证(类似淘宝要加入购物车必须先登录这样子).
      • 统一编码处理,我们当提交表单的方式为post的时候,我们都要设置request的编码防止乱码.
      • 敏感字符过滤.
  3. filter快速入门

    1. 步骤
      1. 定义一个类,实现接口Filter,和servlet类似的.
      2. 复写接口中的方法.
      3. 配置拦截路径(即访问什么样的资源过滤器会生效),servlet配置的是访问路径.
        1. 第一种配置方式: web.xml.
        2. 第二种配置方式: 注解(常用),和servlet一样,写在urlPattern后面,且urlPattern几个字可以省略,一般后面写/*,表示访问所有资源之前都要先执行过滤器,写/demo.jsp则表示只有访问demo.jsp的时候才会执行过滤器.
      4. 放行,即让访问的资源中的内容显示出来
        • chain.doFilter(req, resp);, 其中的chain, req, resp这都是doFilter中的参数.
    2. 过滤器快速入门代码.
    3. 过滤器快速入门index.jsp页面.
    4. 这里有一个点要注意一下,就是如果你配置过滤器为/*的时候,就表示访问所有资源都要先执行过滤器,此时运行服务器,通过上面的代码,访问index.jsp,会发现index.jsp中的内容不会被显示出来,这个就可以理解为这样子: 假设我要回家.路上有土匪,这个土匪就相当于那个过滤器,我能不能过去,就要看土匪能不能放我过去,这就相当于上面的我访问index.jsp前执行了过滤器,我能不能显示index.jsp的内容,要看过滤器让不让我看这样子.
  4. 过滤器的细节

    1. web.xml配置(反正我一般不用hhh,知道就行)

       <filter>
       	<filter-name>demo1</filter-name>
       	<filter-class>这里填的是src下(不包括src)到资源文件的路径(就是包名.包名...类名)如`filters.IntroductionOfFilter`</filter-class>
       </filter>
      
       <filter-mapping>
       	<filter-name>demo1</filter-name>
       	<url-pattern>/*(注意这个是拦截路径,不是访问路径)</url-pattern>
       </filter-mapping>
      
    2. 过滤器执行流程

      • 大体来说就是,先通过对应的url访问资源,然后途中经过过滤器,过滤器经过处理后放行,放行后执行url对应资源的内容,结束之后又回到过滤器中,执行放行语句后面的操作.
      1. 放行语句前,会收到浏览器传来的请求,如果有操作request的语句,它会先执行操作request的语句.
      2. 执行放行语句,回到资源文件中执行相应操作.
      3. 资源文件执行结束后,回到过滤器中,执行放行语句下面的操作,即对相应消息的操作.
    3. 过滤器生命周期方法(三个)

      1. 服务器启动时创建Filter对象,然后由该对象执行init()方法去加载资源,而且只执行一次 —> 每一次浏览器访问服务器经过过滤器时,由Filter对象去执行doFilter()方法,可以执行多次 —>服务器停止时,Filter对象被销毁,如果服务器正常关闭(就是点红色的点,不是直接关闭之前说的tomcat窗口,反正我们在集成开发环境中点击关闭都是正常关闭的),此时执行destroy()释放资源,只执行一次.
    4. 过滤器配置详解

      1. 拦截路径配置(有4种)
        1. 拦截具体的资源路径: /index.jsp, 表示只有访问index.jsp资源时,过滤器才会被执行.
          • 注意,这里是不存在一个项目中有两个同名的index.jsp的,不管你在什么地方,都会报错的.
        2. 拦截具体目录: /user/*, 表示访问/user下的所有资源时,过滤器都会被执行
          • 这里的/user/*不一定非得是一定存在user这个目录,也就是说/user/servlet并不一定表示servlet就放在真正存在的user包下,它只是表示所有前面有/user的url都会被user这个东西限制,也就是会经过过滤器.
          • 如果真的是有这个目录,那么就要把东西放在目录下,同时在idea中要注意这里拦截的是具体目录不是模块包哈,目录和模块包有区别的,目录是自己新建的,模块包是idea生成的,如src,web模块包等,同时这样设置以后,访问的url也要变了,要加上目录了就要.
        3. 后缀名拦截的方式: *.jsp, 表示访问所有后缀名为.jsp资源时,过滤器都会被执行,注意前面没有斜杠.
        4. 拦截所有资源: /*, 表示访问所有资源时,过滤器都会被执行.
        5. 拦截路径设置代码.
      2. 拦截方式配置(两种方式): 指的是资源被访问的方式, 也就是说,比如我设置了浏览器直接访问资源的过滤器,当我从服务器内部转发的时候,就不会被拦截,但是重定向这种两次请求的就也会被拦截.
        1. 注解配置: 在注解filter注解中设置dispatcherTypes属性(有5种取值)
          • REQUEST: 默认值.表示浏览器直接请求资源url,即直接在地址栏输入url路径访问.
          • FORWEAD: 服务器内部转发访问资源.
          • INCLUDE: 包含访问资源(了解)
          • ERROR: 错误跳转资源(了解)
          • ASYNC: 异步访问资源(了解)
          • 当我既要在直接访问时能被过滤器加强,还要在内部转发时也被过滤器加强怎么办呢?
            • 其实很简单,我们通过看webfilter的源码知道,它的dispatcherTypes属性是一个数组,所以我们直接这样写: dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST}.
          • 当这样写的时候: urlPatterns = "/*", dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST}, 表示转发和直接请求访问所有类型资源都会被过滤器加强,但是这样子的话,假如是以请求转发的方式访问index.jsp,过滤器就会被执行两次.
        2. web.xml配置:
          1. 配置资源路径的时候多设置这样一个标签即可,也有上述五个取值,一样的.
        3. 注解配置拦截方式代码.
    5. 过滤器链(配置多个过滤器)

      1. 执行顺序: 如果有两个过滤器(过滤器1,过滤器2)

        • 过滤器1先执行
        • 过滤器2再执行
        • 资源执行
        • 过滤器2回来执行
        • 过滤器1回来执行
      2. 这个怎么测试呢?其实很简单,你就直接写两个过滤器,采用注解配置,其中过滤的url写成/*,然后随便访问一个路径,比如index.jsp的路径,然后你就会发现它两个都执行了(在注解配置中只要两个的filterName不一样,就会都执行,两个名字一样就只会执行前一个).

    
    	@WebFilter(filterName = "FilterDemo4", urlPatterns = "/*")
    	public class FilterDemo4 implements Filter {
        public void destroy() {
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            System.out.println("FilterDemo4执行了");
    
            chain.doFilter(req, resp);
    
            System.out.println("FilterDemo4回来了");
        }
    
        public void init(FilterConfig config) throws ServletException {
    
        }
    
    }
    
    
     3. 过滤器的先后顺序问题(两种):
     	1. 注解配置的过滤器: 根据类名,按照字符串比较规则去比较,值小的先执行.
     		* 例如: AFilter和BFilter,它会先第一个字符比较,然后第二个字符比较...一次类推,在这里,第一个字符`A`<`B`,就比较出来了,所以先执行AFilter.
     		* 又比如: `Filter6`和`Filter17`,它依次比较,比较到`6` > `1`,所以Filter17会先执行.
     	2. web.xml配置: 谁定义在上面谁先执行,就是谁写在前面就先执行谁,知道就好了.
    

Filter案例

  1. 案例1_登录验证
    • 需求
      • 访问之前的用户增删查改的案例的资源。验证其是否登录,即权限控制.
        • 如果登录了,则直接放行。
        • 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录".
  2. 案例2_敏感词汇过滤
    • 需求
      • 对用户增删查改案例录入的数据进行敏感词汇过滤
      • 敏感词汇比如坏蛋``菜鸟等.
      • 如果是敏感词汇,替换为 ***.
    • 分析:
      • 对request对象进行增强,增强获取参数的方法,获取敏感词汇变成***以后要将***再放回到request中,而request没有addParameter方法.
      • 增强后,放行,传递代理对象.
    • 增强对象的功能:
      • 设计模式: 一些通用的解决固定问题的方式.
        • 装饰模式.
        • 代理模式(我们用这个).
          • 概念: 可以理解为代理商,代购
            • 真实对象: 即被代理的对象,比如说我们要买国外的东西,找了代购,国外的东西就是真实对象.
            • 代理对象: 即代理的对象,比如说我们要买东西的找的代购,就是代理对象,但是代理对象还是要去国外买真实对象,然后赚取差价.
            • 代理模式: 代理对象代理真实对象,达到增强真实对象的目的.
            • 可以这么理解,代理商并没有卖电脑的功能,它只是增强总部卖电脑的动能,它要卖电脑,它就要去总部,也就是真实对象那里获取它卖电脑的功能.
          • 实现方式
            • 静态代理: 代理对象的生成方式—>有一个java的类文件描述代理模式.
            • 动态代理: 代理对象的生成方式—>在内存中动态形式代理类,我们这里用动态代理.
          • 实现步骤:
            • 代理对象和真实对象实现相同的接口.
            • 在使用代理对象的方法中,通过语句:代理对象=Proxy.newProxyInstance()创建代理对象.
            • 使用代理对象去调用对应方法.
            • 增强方法.
          • 增强方式:
            • 增强参数列表.
            • 增强返回值类型.
            • 增强方法体执行逻辑
        • 动态代理案例代码.
  3. 实现上述功能后完整代码.

Listener

  1. Listener: 监听器,web的三大组件之一,不过用的比较少,我就没怎么管嘿嘿嘿.

  2. 事件监听机制

    1. 事件: 一件事情.
    2. 事件源: 时间发生的地方.
    3. 监听器: 一段代码或一个对象.
    4. 注册监听: 将事件,事件源,监听器绑定在一起,当事件源发生时间后,执行监听器代码.
  3. servletContextListener(接口,自己写实现类作为监听器对象): 表示监听servletContext对象的创建和销毁.

    1. void contextInitialized(ServletContextEvent sce): servletContext对象创建后会调用该方法.
    2. void contextDestroyed(ServletContextEvent sce): servletContext对象销毁前会调用此方法.
  4. 步骤:

    1. 定义一个类实现servletContextListener接口.
    2. 重写方法.
    3. 配置
      1. web.xml配置.
        • xml配置只需要配置一个就可以了,注意这里的路径是全路径,就是src下从包名开始.包名.类名.
      2. 注解配置.
        • 直接写一个@WebListener就完事了.
    4. 案例代码.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值