JavaWeb——Filter过滤器
1、Filter的目的
Filter用于在Servlet之前检测和修改请求和响应,它可以拒绝、重定向或转发请求。常见的有这几种:
- 日志过滤器
使用过滤器记录请求,提供请求日志记录,还可以添加追踪信息用于特定的请求。
- 验证过滤器
用于验证用户已经“登陆”,很多Servlet的操作都需要验证用户的身份权限,验证过滤器就是把这一功能提取出来,将验证和授权操作集中带一个位置,方便开发和维护
- 压缩和加密过滤器
其实根本上的目的和上一个验证过滤器一样,不过这里的功能是压缩和加密
- 错误处理过滤器
对于客户端来说,有时候出现错误错误通常会返回一个Http响应代码500,一般还伴随这一些诊断信息,通常这些信息对于开发者而言是有用的,但是对于黑客来说,这些诊断信息可能暴露一些敏感的系统信息,而且错误几乎是不可避免的,所以我们需要防止这些信息泄露,使用错误处理过滤器为用户显示一个特殊的页面,比如这个,url是我随便填的一个:

2、创建Filter
其实Filter只是一个接口,源代码如下:
public interface Filter {
void init(FilterConfig var1) throws ServletException;
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
void destroy();
}
- init()方法用于初始化过滤器,这里可以看到一个FilterConfig类,Filter就是使用这个类来进行初始化配置
- doFilter()方法就是用来实现具体功能,检测和修改请求和响应,因为一个项目可能不止需要一个Filter,就比如某个Servlet需要先验证再加密压缩,可能就需要使用两个Filter,这样就形成了一个过滤器链,验证的Filter成功后再将请求传递给加密压缩的Filter,FilterChain将用于传递请求和响应。
- destroy()方法将用于销毁Filter
3、Filter链
通常只有一个Servlet可以处理请求,但可以使用许多过滤拦截请求。一个请求将被很多过滤器处理后传递最终传递给Servlet。如图所示这样:

这样的工作方式被称为过滤器链,这种工作方式相当于一个工作栈,当请求进入时,第一个过滤器将被添第一个过滤器将被添加到栈中,然后再把第二个过滤器添加到栈中,直到最终的Servlet,这是栈的最后一个元素,当Servlet的请求完成的时候,Servlet将从栈中去除,然后控制权将返回最后一个过滤器,然后再移除最后一个过滤器,一直到第一个过滤器中,当栈空的时候,请求处理也就完成了。
4、Filter的部署方式
Filter除了可以映射到某个URL上,某个Servlet上,还可以映射到不同的请求派发器类型,在Servlet容器中有这么几种派发请求方式:
- 普通请求:通常来自客户端,,并包含了容器中特定的Web应用程序的目标URL
- 转发请求:当代码调用RequestDispatcher的forward方法或者使用<jsp:forward>标签是将触发这些请求。
- 包含请求:使用<jsp:include>标签或者调用RequestDispatcher的include方法的时候,将会产生一个不同的、与原始请求相关的内部请求
- 错误资源请求:访问HTTP错误的错误页面的请求
- 异步请求
部署Filter有两种方式,第一种是使用部署描述符
<filter>
<filter-name>filterA</filter-name>
<filter-class>filter.FilterA</filter-class>
</filter>
<filter-mapping>
<filter-name>filterA</filter-name>
<url-pattern>/filterA</url-pattern>
<servlet-name>someServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
- <filter-name>将指定filter的名字
- <filter-class>将指定filter的类名
- <url-pattern>将指定映射的URL
- <servlet-name>将指定映射的Servlet的名字
- <dispatcher>将响应的请求的派发方式,有效的<dispatcher>类型有REQUEST、FORWARD、INCLUDE、ERROR、ASYNC
使用注解:
@WebFilter(
filterName = "filterA",
urlPatterns = {"/filterA","/filterB"},
servletNames = {"someServlet"},
dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.ASYNC}
)
5、过滤器排序
- 匹配请求的过滤器将按照它们出现在部署描述符的顺序添加到过滤器链中
- URL映射的过滤器优先级比Servlet名称映射的过滤器优先级高
定义三个Filter,分别为FilterA、FilterB、FilterC,三个Filter在启动的时候都会输出类名+start,然后将请求和响应传递给下一个Filter,到出栈之前都会输出类名+end
public class FilterA implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterA start");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("FilterA end");
}
@Override
public void destroy() {
}
}
然后定义一个Servlet,这里就是启动的时候输出“ServletOne.doget() start”,结束的时候输出“ServletOne.doget() start”
@WebServlet(
name = "servletOne",
urlPatterns = "/servletOne"
)
public class ServletOne extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("ServletOne.doget() start");
resp.getWriter().write("ServletOne");
System.out.println("ServletOne.doget() end");
}
}
然后这样配置Filter:
<filter>
<filter-name>filterA</filter-name>
<filter-class>filter.FilterA</filter-class>
</filter>
<filter-mapping>
<filter-name>filterA</filter-name>
<servlet-name>servletOne</servlet-name>
</filter-mapping> <filter>
<filter-name>filterB</filter-name>
<filter-class>filter.FilterB</filter-class>
</filter>
<filter-mapping>
<filter-name>filterB</filter-name>
<url-pattern>/servletOne</url-pattern>
</filter-mapping> <filter>
<filter-name>filterC</filter-name>
<filter-class>filter.FilterC</filter-class>
</filter>
<filter-mapping>
<filter-name>filterC</filter-name>
<url-pattern>/servletOne</url-pattern>
</filter-mapping>
FilterA将映射到名称为servletOne的Servlet,FilterB、FilterC都将映射的URL是/servletOne。运行成功之后在浏览器中输入http://localhost:8080/hello-world/servletOne,我们将在IDEA的输出中看到这样的结果
filter.FilterB@17f58a6f start
filter.FilterC@193266e1 start
filter.FilterA@1d0de11fstart
ServletOne.doget() start
ServletOne.doget() end
filter.FilterA@1d0de11f end
filter.FilterC@193266e1 end
filter.FilterB@17f58a6f end
可以看到最先启动的是FilterB,其次是FilterC,最后是FilterA。因为FilterA是映射的Servlet的名称而FilterB、FilterC都是映射的URL所以FilterA将在最后启动,同时也在Servlet结束后结束。因为FilterB在部署时在FilterC之前所以FilterB是最先被启动的,最后结束的。
JavaWeb——Filter过滤器的更多相关文章
- JavaWeb基础—过滤器Filter
一.概念 JavaWeb三大组件之一(组件都有一个特性,需要在web.xml中配置) 过滤器:会在一组资源(jsp servlet等)的前面执行,可以让请求得到目标资源,也可以终止请求,不再继续 也就 ...
- 【JavaWeb】Filter 过滤器
Filter 过滤器 简介 Filter 过滤器是 JavaWeb 三大组件之一 Filter 过滤器是 JavaEE 的规范,也就是接口 Filter 过滤器的作用是 拦截请求,过滤响应 拦截请求的 ...
- javaweb学习总结(四十二)——Filter(过滤器)学习
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...
- javaWeb学习总结(10)- Filter(过滤器)学习
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有 web资源:例如Jsp, Servlet, 静 ...
- JavaWeb(五)Filter过滤器
Filter过滤器 Fileter介绍 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Serv ...
- javaweb之Filter过滤器详解
快速入门 1.新建一个类,实现Filter接口 2.实现doFilter()方法,打印一句话,来证明能够进行拦截 3.在web.xml中进行配置(参照Servlet配置) 4.访问一个页面,看看能不能 ...
- JavaWeb学习篇--Filter过滤器
Filter过滤器简介 ServletAPI中提供了一个Filter接口,开发web应用时,如果编写的 java 类实现了这个接口,则把这个java类称之为过滤器Filter. WEB服务器每次在调用 ...
- Filter(过滤器)常见应用
孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(四十六)——Filter(过滤器)常见应用 一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html F ...
- Filter(过滤器)
一.Filter过滤器(重要) Javaweb中的过滤器可以拦截所有访问web资源的请求或响应操作. 1.Filter快速入门 1.1.步骤: 1. 创建一个类实现Filter接口 2. 重写接口中方 ...
随机推荐
- c++复杂桶排序Java版
c++复杂桶排序Java版 题目和我的前几个排序一样 这次是Java版的 代码 + 注释 package com.vdian.qatest.supertagbiz.test.niu; /** * Cr ...
- ZigBee入门第一天
按键查询控制灯的状态 1.宏定义灯和按键 2.按键和灯初始化 3.用if语句消抖的方法,实现按键控制灯的状态 相关寄存器 PxSEL PxDIR #include"ioCC2530.h&qu ...
- OSPF 单区域实验
实验拓扑 实验需求 按照图示配置 IP 地址 按照图示分区域配置 OSPF ,实现全网互通 为了路由结构稳定,要求路由器使用环回口作为 Router-id 实验步骤 每台路由器都要将本地的所有直连网段 ...
- 【朝花夕拾】Android自定义View篇之(十)TouchSlop及VelocityTracker
前言 在Android事件中,有几个比较基本的概念和知识点需要掌握.比如,表示最小移动阈值的TouchSlop,追踪事件速度的VelocityTracker,用于检测手势的GestureDetecto ...
- 剑指offer第二版-10.斐波那契数列
面试题10:斐波那契数列 题目要求: 求斐波那契数列的第n项的值.f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2) n>1 思路:使用循环从下往上计算数列. 考点:考察对递归 ...
- Linux操作系统下文件作用
linux下的文件结构,看看每个文件夹都是干吗用的 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的 ...
- Socket编程(C语言实现):socket()函数英文翻译
最近开始研究使用Socket API来网络编程,想着把自己的感想.感悟写下来.我发现在编程之外还有不少概念性的东西要学习.我觉得应该有以下几点吧: 1.得了解下计算机网络的基本概念,如OSI的7层模型 ...
- Maven(三)使用 IDEA 创建一个 Maven 项目
利用 IDEA 创建一个 Maven 项目 创建 Maven 项目 选择 File --> New --> Project 选中 Maven 填写项目信息 选择工作空间 目录结构 ├─sr ...
- PJzhang:python基础入门的7个疗程-five
猫宁!!! 参考链接:易灵微课-21天轻松掌握零基础python入门必修课 https://www.liaoxuefeng.com/wiki/1016959663602400 第十三天:代码组织 类是 ...
- idea的安装与配置及基本用法
Intellij IDEA 确实使用更加方便,由于目前只用到maven项目,所以此处只记录maven项目的配置. 一.配置idea前准备: 1.下载idea安装包.jdk安装包.maven安装包.gi ...