zoukankan      html  css  js  c++  java
  • Web核心之Filter过滤器

    Filter过滤器概念:

    过滤器是web中的一个组件,可以用于过滤请求。在服务器目标资源之前优先拦截到请求,对其进行处理,可以放行该请求也可以直接拦截掉。如果请求被放行,那么该请求的响应也会被过滤器拦截。

    Filter过滤器作用:可以完成一系列通用的操作。

    Filter过滤器编写流程:

    1. 编写一个类实现Filter接口
    2. 实现接口中的方法,重点是doFilter方法在doFilter方法中,可以调用chain.doFilter实现请求的放行
    3. 通过配置告知tomcat服务器Filter的信息
      全类名


    拦截路径

    在web.xml中配置:

    <filter>
    	 <filter-name>demo1</filter-name>
    	 <filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>demo1</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>
    

    使用注解配置:

    @WebFilter

    只要访问的资源路径符合拦截路径的规则,那么该请求就优先被过滤器拦截到

    拦截路径配置:

    完全路径匹配[具体资源路径]:

    以/开头, 后面是一个明确的字符串。要求访问路径和指定的路径必须完全一致,如/xxx/aaa/bbb/index.jsp
    只有访问index.jsp资源时,过滤器才会被执行

    目录匹配[拦截目录]:

    以/开头,结尾,中间有多层目录结构的。要求路径跟指定的目录一致即可,如/user/*
    访问/user下的所有资源时,过滤器都会被执行

    扩展名匹配[后缀名拦截]:

    以开头,以.xxx结尾。要求路径要以某个扩展名结尾,如*.jsp
    访问所有后缀名为jsp资源时,过滤器都会被执行

    缺省路径匹配[拦截所有资源]:如果没有任何其他的规则可以匹配资源访问路径,则分配给缺省路径,为/*

    访问所有资源时,过滤器都会被执行

    优先级:无。注意:Filter的url-pattern配置没有优先级的规则。如果多个Filter拦截规则都能匹配到某个请求的访问路径。这些Filter都能拦截到这次请求,它们会按照某种规则组成一条过滤器链。

    拦截方式:

    资源被访问的方式[直接请求资源,转发访问资源,包含访问资源,错误跳转资源,异步访问资源]

    拦截方式配置[注解配置]:

    设置dispatcherTypes属性

    1. REQUEST:默认值。浏览器直接请求资源

    2. FORWARD:转发访问资源

    3. INCLUDE:包含访问资源

    4. ERROR:错误跳转资源

    5. ASYNC:异步访问资源

    配置请求方式:设置dispatcherTypes属性 分发类型

    REQUES[默认值,浏览器直接请求资源]访问index.jspT举例:


    Servlet转发访问index.jsp:

    结果:

    直接访问:


    转发访问:

    FORWARD[转发访问资源]举例:


    Servlet转发访问index.jsp:

    直接访问:


    转发访问:

    FilterChain过滤器链

    组成:

    如果多个Filter拦截规则都能匹配到某个请求的访问路径。这些Filter都能拦截到这次请求,它们会按照某种规则组成一条过滤器链。
    例如:



    执行顺序规则:

    如果Filter是使用注解配置,在链中的顺序和类名的字符串顺序一致。

    如果Filter是使用web.xml配置,在链中的顺序和filter-mapping标签配置的上下顺序一致,如果是:

    <filter-mapping>FilterB<filter-mapping> 
    <filter-mapping>FilterA<filter-mapping> 
    

    那就FilterB先执行。

    登陆验证案例:

    执行流程:

    调用chain.doFilter()时,内部实际进行了判断,判断当前过滤器链中是否有下一个过滤器节点。如果有,则调用其doFilter方法。如果没有,则放行到目标资源位置。在一个过滤器链中,只有所有的过滤器都执行了chain.doFilter,那么这次请求才能访问到目标资源。只要有一个过滤器拦截住没有放行,那么整条过滤器链相当于就没有放行。

    过滤器生命周期方法

    1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
    2. doFilter:每一次请求被拦截资源时,会执行。执行多次
    3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源

    登录验证案例
    1. 挑选出可以直接放行的资源---登录相关的资源。
    2. 使用Filter,拦截所有请求,判断是否登录。
    3. 用户是否处于登录状态,是由session中是否存储了user信息决定的。

    动态代理:

    在不修改一个类的源码的基础上,动态的修改其方法的执行逻辑,来增强一个类中的方法

    1. 继承 前提:目标对象必须是我们自己控制创建的。

    2. 装饰者模式

    如:new BufferedReader(new InputStreamReader(new FileInputStream("C://xxx")));

    3. 动态代理

    代理:代替你去处理一些逻辑。

    动态代理:通过api,动态的在运行期生成一个类的对象,作为代理对象使用。

    基于JDK的动态代理的规则:我们的被代理对象要实现接口。
    代理对象 = Proxy.newProxyInstance()
    Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

    InvocationHandler 接口的实现:

    参数:

    ClassLoader:被代理对象的类加载器
    固定写法:被代理对象.getClass().getClassLoader()
    Class<?>[]: 被代理对象实现的所有接口对应的字节码对象
    固定写法:被代理对象.getClass().getInterfaces()
    InvocationHandler:调用的处理器接口,用于指定代理对象中的所有方法的执行逻辑的。
    Object invoke(Object proxy, Method method, Object[] args)---当代理对象的方法被调用时,实际执行的是该方法。该方法的返回值会返回到代理对象调用方法处。

    举例说明动态代理:

    背景:有一个黑心的SK2代理商,以官方途径售卖SK2(强调卖SK2是宝洁官方的方法,代理没有卖SK2的方法,只是能辅助官方售卖),对SK2进行一些操作提高利润。

    卖SK2的接口:

    SK2类:

    黑心代理类:


    真实对象sk2调用sk2的方法:

    黑心代理类内部用代理对象proxyInstanceOfSK2调用真实对象sk2的方法:


    代理对象proxyInstanceOfSK2什么事都没干,但是每一次调用真实对象sk2的方法都会执行一次invoke方法。

    由于黑心代理并不具备卖SK2的功能,她只是通过SK2的官方渠道来卖SK2,是调用SK2官方的方法来进行售卖

    修改代理类的invoke方法:

    再用代理对象proxyInstanceOfSK2调用真实对象sk2的方法得到如下结果:


    invoke方法当method为sale时的返回值会返回到代理对象proxyInstanceOfSK2调用sale时的返回值。

    在invoke方法中添加黑心代理的销售手段:


    动态代理实现敏感词过滤:

    Listener

    监听器
    	当某个具体的事件发生时,可以执行提前设定好的一段逻辑。监听器封装了这些逻辑。
    ServletContextListener
    	监听ServletContext对象的创建和销毁的监听器。
    	监听此对象相当于监听了服务器的启动和关闭。
    编写流程
    	写一个类实现ServletContextListener接口
    	实现接口中的方法
    		创建
    		销毁
    	在web.xml中进行配置
    		<listener>
    

    全局初始化参数
    在web.xml中,使用context-param标签可以指定key-value键值对的参数,使用ServletContext对象就可以使用key来获取这些参数。

    key
    value

    String value = servletContext.getInitParameter("key");

    在web.xml中,在servlet或filter标签下,也可以使用init-param指定key-value键值对的参数
    	<init-param>
    	    <param-name>key</param-name>
    	    <param-value>value</param-value>
    	</init-param>
    如果在Filter中,可以使用filterConfig.getInitParameter("key")获取指定的值
    如果在Servlet中,可以使用this.getServletConfig().getInitParameter("key")获取指定的值
  • 相关阅读:
    VS工作目录,输出目录
    Google的C++开源代码项
    C++文件读写
    深拷贝浅拷贝
    Efficient Graph-Based Image Segmentation
    Graph Cut 简介
    Graph Cut
    "GrabCut" - Interactive Foreground Extraction using Iter
    EM算法
    Python图像处理库(2)
  • 原文地址:https://www.cnblogs.com/maomaodesu/p/12115175.html
Copyright © 2011-2022 走看看