过滤器(Filter)

1 什么是过滤器

过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。

当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。

 

其实过滤器与Servlet很相似,我们回忆一下如果写的第一个Servlet应用!写一个类,实现Servlet接口!没错,写过滤器就是写一个类,实现Filter接口。

public class HelloFilter implements Filter {public void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("Hello Filter");}public void destroy() {}
}
  <filter><filter-name>helloFilter</filter-name><filter-class>cn.itcast.filter.HelloFilter</filter-class></filter><filter-mapping><filter-name>helloFilter</filter-name><url-pattern>/index.jsp</url-pattern></filter-mapping>
过滤器的生命周期

 

我们已经学习过Servlet的生命周期,那么Filter的生命周期也就没有什么难度了!

 

   init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;

 

  doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户每次访问“目标资源(<url->pattern>index.jsp</url-pattern>)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;

 

  destroy():服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

 

 

 

FilterConfig

你已经看到了吧,Filter接口中的init()方法的参数类型为FilterConfig类型。它的功能与ServletConfig相似,与web.xml文件中的配置信息对应。下面是FilterConfig的功能介绍:

   ServletContext getServletContext():获取ServletContext的方法;

  String getFilterName():获取Filter的配置名称;与<filter-name>元素对应;

   String getInitParameter(String name):获取Filter的初始化配置,与<init-param>元素对应;

   Enumeration getInitParameterNames():获取所有初始化参数的名称。

 

FilterChain

doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法:doFilter(ServletRequest,ServletResponse)。

前面我们说doFilter()方法的放行,让请求流访问目标资源!但这么说不严密,其实调用该方法的意思是,“我(当前Filter)”放行了,但不代表其他人(其他过滤器)也放行。

也就是说,一个目标资源上,可能部署了多个过滤器,就好比在你去北京的路上有多个打劫的匪人(过滤器),而其中第一伙匪人放行了,但不代表第二伙匪人也放行了,所以调用FilterChain类的doFilter()方法表示的是执行下一个过滤器的doFilter()方法,或者是执行目标资源!

如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,而不是最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。

 

多个过滤器执行顺序

一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序:

 

  <filter><filter-name>myFilter1</filter-name><filter-class>cn.itcast.filter.MyFilter1</filter-class></filter><filter-mapping><filter-name>myFilter1</filter-name><url-pattern>/index.jsp</url-pattern></filter-mapping><filter><filter-name>myFilter2</filter-name><filter-class>cn.itcast.filter.MyFilter2</filter-class></filter><filter-mapping><filter-name>myFilter2</filter-name><url-pattern>/index.jsp</url-pattern></filter-mapping>
public class MyFilter1 extends HttpFilter {public void doFilter(HttpServletRequest request, HttpServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("filter1 start...");chain.doFilter(request, response);//放行,执行MyFilter2的doFilter()方法System.out.println("filter1 end...");}
}
public class MyFilter2 extends HttpFilter {public void doFilter(HttpServletRequest request, HttpServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("filter2 start...");chain.doFilter(request, response);//放行,执行目标资源System.out.println("filter2 end...");}
}
<body>This is my JSP page. <br><h1>index.jsp</h1><%System.out.println("index.jsp"); %></body>

 

 

输出结果

filter1 start...

filter2 start...

index.jsp

 

四种拦截方式

 

分别是:REQUEST、FORWARD、INCLUDE、ERROR。

 

   REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;

 

  FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;

 

  INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;

 

  ERROR:当目标资源在web.xml中配置为<error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。

 

可以在<filter-mapping>中添加0~n个<dispatcher>子元素,来说明当前访问的拦截方式。

    <filter-mapping><filter-name>myfilter</filter-name><url-pattern>/b.jsp</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping><filter-mapping><filter-name>myfilter</filter-name><url-pattern>/b.jsp</url-pattern></filter-mapping><filter-mapping><filter-name>myfilter</filter-name><url-pattern>/b.jsp</url-pattern><dispatcher>FORWARD</dispatcher></filter-mapping>
过滤器的应用场景

过滤器的应用场景:

  执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;[c1] 

  通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

   在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理[c2] ;


 [c1]几乎是的Sevlet中都需要写request.setCharacterEndoing() 可以把它入到一个Filter中

 [c2]回程拦截!

 

 

设置目标资源

web.xml文件中部署Filter时,可以通过“*”来执行目标资源:

<filter-mapping><filter-name>myfilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

 

这一特性与Servlet完全相同!通过这一特性,我们可以在用户访问敏感资源时,执行过滤器,例如:<url-pattern>/admin/*<url-pattern>,可以把所有管理员才能访问的资源放到/admin路径下,这时可以通过过滤器来校验用户身份。

还可以为<filter-mapping>指定目标资源为某个Servlet,例如:

<servlet><servlet-name>myservlet</servlet-name><servlet-class>cn.itcast.servlet.MyServlet</servlet-class></servlet><servlet-mapping><servlet-name>myservlet</servlet-name><url-pattern>/abc</url-pattern></servlet-mapping><filter><filter-name>myfilter</filter-name><filter-class>cn.itcast.filter.MyFilter</filter-class></filter><filter-mapping><filter-name>myfilter</filter-name><servlet-name>myservlet</servlet-name></filter-mapping>

 当用户访问http://localhost:8080/filtertest/abc时,会执行名字为myservlet的Servlet,这时会执行过滤器。

 

Filter小结

Filter的三个方法:

  void init(FilterConfig):在Tomcat启动时被调用;

  void destroy():在Tomcat关闭时被调用;

  void doFilter(ServletRequest,ServletResponse,FilterChain):每次有请求时都调用该方法;

 

FilterConfig类:与ServletConfig相似,用来获取Filter的初始化参数

  ServletContext getServletContext():获取ServletContext的方法;

  String getFilterName():获取Filter的配置名称;

  String getInitParameter(String name):获取Filter的初始化配置,与<init-param>元素对应;

  Enumeration getInitParameterNames():获取所有初始化参数的名称。

 

FilterChain类:

  void doFilter(ServletRequest,ServletResponse):放行!表示执行下一个过滤器,或者执行目标资源。可以在调用FilterChain的doFilter()方法的前后添加语句,在FilterChain的doFilter()方法之前的语句会在目标资源执行之前执行,在FilterChain的doFilter()方法之后的语句会在目标资源执行之后执行。

 

四个拦截方式:REQUEST、FORWARD、INCLUDE、ERROR,默认是REQUEST方式。

  REQUEST:拦截直接请求方式;

   FORWARD:拦截请求转发方式;

   INCLUDE:拦截请求包含方式;

  ERROR:拦截错误转发方式。

 

 

转载于:https://www.cnblogs.com/flei/p/7269913.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

发布适用于 .NET 7 的 .NET MAUI

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;6分钟)我们在六个月前向您介绍了 .NET 多平台应用程序 UI (MAUI)&#xff0c;现在我们很高兴地宣布 .NET MAUI 在我们的下一个主要版本 .NET 7 中普遍可用。在此短的时间范围内&#xff0c;我们在 .NET MAUI 中的主要…

03:数据结构 栈、队列、链表与数组

算法其他篇 目录&#xff1a; 1.1 数据结构中的一些概念1.2 栈&#xff08;stack&#xff09;1.3 队列1.4 链表1.5 python中字典对象实现原理1.6 数组1.1 数据结构中的一些概念 返回顶部 1、数据结构是什么 1、简单来说&#xff0c;数据结果就是设计数据以何种方式存储在计…

力登:以智能化管理提升数据中心服务能力成熟度

2017年2月28日&#xff0c;由全国信息技术标准化技术委员会信息技术服务分技术委员会指导的《信息技术服务数据中心服务能力成熟度模型》发布&#xff0c;在业界首次提出“数据中心服务能力成熟度”概念&#xff0c;使得数据中心的管理真正实现了数字化和持续优化&#xff0c;是…

基于.NET 7 的 WebTransport 实现双向通信

Web Transport 简介WebTransport 是一个新的 Web API&#xff0c;使用 HTTP/3 协议来支持双向传输。它用于 Web 客户端和 HTTP/3 服务器之间的双向通信。它支持通过 不可靠的 Datagrams API 发送数据&#xff0c;也支持可靠的 Stream API 发送数据。因为 HTTP/3 使用了基于 UDP…

Django01: 安装/基础命令/设置笔记

安装 按官网版本支持&#xff0c;现在比较适合使用1.11版本。 下载安装命令 pip3 install django1.11.9 新建项目 django-admin startproject mysite 运行项目 python manage.py runserver 127.0.0.1:8000 运行相关 目录介绍 mysite/ ├── manage.py # 管理文件 └…

线上问题随笔记录数据库连接池问题

修改方法 转载于:https://www.cnblogs.com/lvgg/p/8581506.html

数据底座_体验当今计算机的未来:通过智能底座将您的Galaxy S4变成PC

数据底座Have you ever thought that Smartphones these days are so advanced they could actually replace the PC in your everyday computing life? Today, we here at HTG will review using the Galaxy S4 with the “Smart Dock Multimedia Hub” as a PC replacement.…

如何实现 WPF 代码查看器控件

如何实现 WPF 代码查看器控件CodeViewer作者&#xff1a;WPFDevelopersOrg - 驚鏵原文链接[1]&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET40&#xff1b;Visual Studio 2019;代码展示需要使用到AvalonEdit是基于WPF的代码显示控件&#xff0c;…

谈大数据也谈人工智能 郭为告诉你一个不一样的神州控股

毋庸置疑&#xff0c;我们深处一个数据无处不在的时代&#xff0c;也就是大数据时代。作为中国智慧城市领导者的神州数码控股有限公司&#xff08;以下简称“神州控股”&#xff09;近年来也在积极布局大数据&#xff0c;不过在神州控股董事局主席郭为看来&#xff0c;神州控股…

Django02: pycharm上配置django

1.setting导入 File-->Setting-->Project-->Project Interface 2.new project 新窗口 圖片畫錯 3.调试 点击右上角调试

dropbox_来自提示框:望远镜激光瞄准器,Dropbox桌面和Kindle剪辑转换

dropboxOnce a week we round up some great reader tips and share them with everyone; this week we’re looking at telescope laser sights, syncing your desktop with Dropbox, and converting your Kindle Clippings file. 每周一次&#xff0c;我们收集一些很棒的读者…

在 EF Core 7 中实现强类型 ID

本文主要介绍 DDD 中的强类型 ID 的概念&#xff0c;及其在 EF 7 中的实现&#xff0c;以及使用 LessCode.EFCore.StronglyTypedId 这种更简易的上手方式。背景在杨中科老师 B 站的.Net Core 视频教程[1]其中 DDD 部分讲到了强类型 ID&#xff08;Strongly-typed-id&#xff09…

如何快速打造一款高清又极速的短视频APP?

2019独角兽企业重金招聘Python工程师标准>>> 整个短视频的市场规模一直在增长&#xff0c;网络数据显示2018年已经突破100亿大关&#xff0c;在2019年预测将超过200亿。纵观行业&#xff0c;在生活资讯、美食、搞笑、游戏、美妆等领域&#xff0c;短视频流量巨大但竞…

Django03: django加入APP

使用命令在已有project创建 1.创建 在manage.py同级运行命令 python manage.py startapp app01 2.django中加入app 在settings.py里的INSTALLED_APPS加入app01.apps.App01Config, INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttype…

如何将Windows 10帐户还原为本地帐户(在Windows Store劫持它之后)

If your Windows 10 user account is currently a Microsoft account (by your choice or because you got, one way or another, roped into it) it’s easy to revert it back to a local account if you know where to look. Read on as we show you how. 如果您的Windows 1…

【译】Dapr 是一个“10倍好”平台 !?

译者注在正式阅读本文之前&#xff0c;我们有必要先了解下什么是“10 倍好”。10 倍好理论最早出自彼得蒂尔的《从 0 到 1》&#xff0c;他说一个新创企业&#xff0c;要想获得快速成长&#xff0c;其提供的解决方案要比现有方案好 10 倍以上&#xff0c;这个好 10 倍&#xff…

1. ReactJS基础(开发环境搭建)

本文主要介绍通过React官方提供的create-react-app脚手架进行开发环境的搭建。 1.安装node环境(安装过程这里不做介绍&#xff0c;可参考其他博文) 在cmd中输入node -v 如果可以看到相应版本号&#xff0c;说明node环境安装成功 2.npm全局安装create-react-app脚手架 3.cmd命令…

“云计算+DevOps”的正确打开方式

以我们的经验看&#xff0c;技术和工具是很重要&#xff0c;但是技术和工具本身却不能产生价值&#xff0c;而将DevOps和云计算结合却可以。事实上&#xff0c;云计算的特性决定了&#xff0c;云计算和DevOps势必如影随形&#xff0c;而云计算与DevOps的结合也正在为企业用户提…

微服务和分布式系统中的授权解决方案

本文是 《精读 Mastering ABP Framework》 2.3 探索横切关注点 - 使用授权和权限系统 一节的扩充内容&#xff0c;重点探讨了授权在分布式和微服务系统中遇到的挑战&#xff0c;以及 ABP Framework 中采用的解决方案。认证 & 授权• 认证&#xff08;Authentication&#x…

如何从命令行浏览和连接到无线网络

() We are always on the lookout for geeky ways to impress our friends, and recently we came across a way to connect to our wireless network from the command prompt, so today we’ll show you how to do it as well. 我们一直在寻找令人印象深刻的方式来打动我们的…