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. 重写接口中方 ...
随机推荐
- while循环的初始以及编码的初始
whlie循环 why:比如要多次重复做一件事情,如歌曲列表循环,银行卡密码错误多次重复! what:whlie无限循环. how: ##基本结构while 条件: 循环体 基本原理 循环如何终 ...
- scrapy基础知识之 parse()方法的工作机制思考:
1.因为使用的yield,而不是return.parse函数将会被当做一个生成器使用.scrapy会逐一获取parse方法中生成的结果,并判断该结果是一个什么样的类型: 2.如果是request则加入 ...
- python爬虫登陆问题
根据腾讯课堂网页登陆问题进行解说(需要安装谷歌浏览器): 1.导入库 import requests from selenium import webdriver 2.根据腾讯课堂链接,进入页面,获取 ...
- MYSQL5.7---ONLY_FULL_GROUP_BY 异常处理
异常介绍: ONLY_FULL_GROUP_BY 指的是你查询的语句使用到了group by 例如 select name,age from person group by sex; 此时你grou ...
- git rebase VS git merge? 更优雅的 git 合并方式值得拥有
写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online ,你可以更直观的看到你所使用的命令会产生什么效果 另外,你在使用 Git 合并分支时只 ...
- Java项目案例之---常用工具类练习
常用工具类练习 1. 请根据控制台输入的特定日期格式拆分日期,如:请输入一个日期(格式如:**月**日****年),经过处理得到:****年**月**日 import java.util.Scanne ...
- ansible安装应用软件
1.创建相应的目录: mkdir -p /ansible/roles/{nginx,mysql,tomcat,db,zabbix}/{defaults,files,handlers,meta,task ...
- Spring Boot 2.x (十八):邮件服务一文打尽
前景介绍 在日常的工作中,我们经常会用到邮件服务,比如发送验证码,找回密码确认,注册时邮件验证等,所以今天在这里进行邮件服务的一些操作. 大致思路 我们要做的其实就是把Java程序作为一个客户端,然后 ...
- 1.jdk1.7到jdk1.8 Map发生了什么变化(底层)?
1.8之后hashMap的数据结构发生了变化,从之前的单纯的数组+链表结构变成数组+链表+红黑树.也就是说在JVM存储hashMap的K-V时仅仅通过key来决定每一个entry的存储槽位(Node[ ...
- Code Review最佳实践
我一直认为Code Review(代码审查)是软件开发中的最佳实践之一,可以有效提高整体代码质量,及时发现代码中可能存在的问题.包括像Google.微软这些公司,Code Review都是基本要求,代 ...