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. 重写接口中方 ...
随机推荐
- jQuery 文本框 光标 移动到 文字最后
方法一:调用办法:setCaretToPos(document.getElementById("YOURINPUT"), 4); function setSelectionRang ...
- JavaScript-浏览器的三种弹窗方式
//BOM 弹窗 //同步 阻断 alert("alert弹窗"); //返回布尔值 (是/否) var bcf = confirm("confirm弹窗"); ...
- [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)
tree 时间限制: 3 Sec 内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...
- 对于springboot的几种注入方法的个人看法
最近在知乎上面看到一篇关于程序员面试的问题,面试官问我们一般有几种注入的方法,这几种注入的方法分别在什么时候运用比合理,当时我看到这个时候懵逼了,由于我自己也是刚刚接触springboot不久,所以就 ...
- 【原创】一个shell脚本记录(实现rsync生产文件批量迁移功能)
#!/bin/bash #Date:2018-01-08 #Author:xxxxxx #Function:xxxxxx #Change:2018-01-17 # #设置忽略CTRL+C信号 trap ...
- 什么是常量?变量? if语句介绍
1.python 的历史 2004 年 Django 的产生 phyton2与 python3 的区别 Python2:源码不统一,有重复的代码功能 Python3:源码统一,没有有重复的代码功能 2 ...
- 网页内嵌html遇到的问题
在项目中遇到个问题 充值功能是点击一个按钮这个按钮会弹出模态框,输入充值金额会执行一段脚本自动提交数据到https://openapi.alipay.com/gateway.do上 结果:本网页跳转到 ...
- 一次使用InfluxDB数据库的总结
前言 因当前的项目需要记录每秒钟服务器的状态信息,例如负载.cpu等等信息,这些数据都是和时间相关联的. 因为一秒钟就要存储挺多的数据.而且我还在前端做了echart的折线图,使用websocket实 ...
- 知识图谱学习与实践(4)——通过例句介绍Sparql的使用
通过例句介绍Sparql的使用 1 简介 SPARQL的定义,是一个递归的定义,为SPARQL Protocal and RDF Query Language,是W3C制定的RDF知识图谱标准查询语言 ...
- Pinyin4j简单使用教程
Pinyin4j是一个流行的Java库,支持中文字符和拼音之间的转换,拼音输出格式可以定制,在项目中经常会遇到需求用户输入汉字后转换为拼音的场景,这时候Pinyin4j就可以派上用场 有自己私服的可以 ...