热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Filter过滤器(1)

Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态

   Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

  其顺序图如下(Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。)

技术分享

过滤器,设计执行流程:

  1. 用户访问服务器
  2. 过滤器: 对Servlet请求进行拦截
  3. 先进入过滤器, 过滤器处理
  4. 过滤器处理完后, 在放行, 此时,请求到达Servlet/JSP
  5. Servlet处理
  6. Servlet处理完后,再回到过滤器, 最后在由tomcat服务器相应用户;

Filter的生命周期

(1)、init(FilterConfig filterConfig)throws ServletException:

  与servlet一样(Filter其实也是一个servlet),Filter的创建和销毁是由web服务器负责的。web服务器一启动,就会调用init()方法,完成对象的初始化功能

  (注:filter对象只会创建一次,init方法也只会执行一次。)

(2)、destroy():

  在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。

(3)、doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

   The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.(大概的意思是在每次请求/响应时由容器创建)过滤器业务拦截的业务处理方法


程序示例

首先写一个要被访问的servlet,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.gqx.filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class IndexServlet extends HttpServlet {
    /**
     * 处理用户http request
     */
    private static final long serialVersiOnUID= 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("4、处理用户请求开始!");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

然后就是去访问之前需要对请求或响应内容做处理的过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.gqx.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
 * 测试的过滤器
 * @author Administrator
 *
 */
public class HelloFilter implements Filter {
    //创建实例
    public HelloFilter() {
    // TODO Auto-generated constructor stub
        System.out.println("1、过滤器用例开始创建了。");
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("2、执行过滤器初始化方法!");
    }
    //过滤器业务处理方法,在请求到达servlet之前进入此方法处理公用的业务逻辑操作
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        System.out.println("3、执行过滤器的业务处理方法!");
        //放行(去到Servlet)
        chain.doFilter(request, response);
     
        System.out.println("5、Servlet处理完成,又回到Filter了!");
    }
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        System.out.println("6、同时过滤器被销毁了!");
    }
}

最后就是要去web.xml中去配置好先关的过滤器设置

1
2
3
4
5
6
7
8
9
10
11
12
13
    
    
    HelloFilter
    
    class>com.gqx.filter.HelloFilterclass>
    
    HelloFilter
    
    /*

一切都ok了现在我在各个打印语句之前都设置了断点,可以观察到如下图所示的变化

技术分享


当有多个过滤器的时候,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    
        
        HelloFilter
        
        class>com.gqx.filter.HelloFilterclass>
    
    
        
        HelloFilter
        
        /*
    
     
    
    
        HelloFiler2
        class>com.gqx.filter.HelloFilter2class>
    
    
        HelloFiler2
        /*
    

同理在第一个HelloFilter的doFilter()的方法中写入

1
2
3
4
5
  System.out.println("3、第一个过滤器:执行过滤器的业务处理方法!");
//放行(去到Servlet)
chain.doFilter(request, response);
System.out.println("5、第一个过滤器:Servlet处理完成,又回到Filter了!");

在HelloFiler2的doFilter()的方法中写入

1
2
3
System.out.println("第二个过滤器!");
        chain.doFilter(request, response);
        System.out.println("第二个过滤器结束了!");

 同样在这些语句中设置断点会发现如下结果

技术分享

这个时候就可以知道服务器启动后,用户去访问,根据xml中的过滤器的先后顺序来执行对应的过滤器,执行其对应的doFilter的方法放行request/response,被放行后他们就进入了第二个过滤器HelloFiler2,被第二个过滤器放行后才会回到对应的servlet,servlet运行完之后,回到第二个过滤器,再回到第一个过滤器。(如下图)

 技术分享


过滤器相关Api

(1)、|-- interface  Filter                            过滤器核心接口

         Void  init(filterConfig);    初始化方法,在服务器启动时候执行

   Void  doFilter(request,response,filterChain);   过滤器拦截的业务处理方法

   Void destroy();                         销毁过滤器实例时候调用

(2)|-- interface  FilterConfig   获取初始化参数信息(方法类似于servletConfig)

  String getInitParameter(java.lang.String name)

  Enumeration getInitParameterNames() 


与servlet同样,在web.xml中配置先关信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    
    
    
        encoding
        UTF-8
    
    
        path
        c:/...
    
    FilterApi
    class>com.gqx.filter.FilterApiclass>
    FilterApi
    /*
   

(注意:有时候会出现错误 cvc-complex-type.2.4.a: Invalid content was found starting with element 这个时候可以将“http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd”这段话加入到xml文件的"xmlns:xsi="的标签中)

如下:

1 "http://www.w3.org/2001/XMLSchema-instance http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

然后就是他的过滤器先关的内容了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class FilterApi implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("获取过滤器在web.xml中配置的初始化参数!");
        String encoding=filterConfig.getInitParameter("encoding");
        System.out.println(encoding);
        //filterConfig.getFilterName() 获取单个
        Enumeration enums=filterConfig.getInitParameterNames();
        while (enums.hasMoreElements()) {
            //获取对应的参数名称
            String name = (String) enums.nextElement();
            //获取对应名称的值
            String value=filterConfig.getInitParameter(name);
            System.out.println(name+"\t"+value);
        }
    }
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub 
    }
}

启动服务器就会看到控制台打印的先关数据

技术分享

(3)、|-- interface  FilterChain     过滤器链参数;一个个过滤器形成一个执行链;

         void doFilter(ServletRequest request, ServletResponse response)  ;  执行下一个过滤器或放行


对指定的请求拦截

刚才看到的是对所有的请求进行拦截

1
2
3
4
  
    FilterApi
    /*
1
2
3
4
5
6
7
@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    // TODO Auto-generated method stub
    System.out.println("指定过滤器的拦截。。。。。");
    chain.doFilter(request, response);
}

当访问index.jsp的时候,就会出现

技术分享

当要对多个指定的请求进行拦截时,可以这样写

1
2
3
4
5
6
7
8
9
10
    
    PontedFilter
    /index.jsp
    /list.jsp
    
    
    /IndexServlet
     

规则有点像servlet的配置

对类型的拦截

1
2
3
4
5
 
REQUEST 
FORWARD 
INCLUDE 
ERROR

默认拦截的类型:(直接访问或者重定向)

REQUEST

拦截转发:

                     FORWARD

拦截包含的页面(RequestDispatcher.include(/page.jsp);    对page.jsp也执行拦截)

                     INCLUDE

拦截声明式异常信息:

                     ERROR

      类似于如下代码

1
2
3
4
5
   
    404
    
    

 如下代码示例

1
2
/*
FORWARD 

 在ServletTets中写下

1 request.getRequestDispatcher("IndexServlet").forward(request, response);

请求的转发就会被拦截住。

Filter过滤器(1)


推荐阅读
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
author-avatar
为谁落慕
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有