过滤器
来源:互联网 发布:江歌的遇害事件知乎 编辑:程序博客网 时间:2024/05/16 13:01
过滤器
什么是过滤器
Filter译为过滤,是JavaEE的三大组件之一,用于在Servlet之外对Request或者Response进行修改。例如,污水净化设备可以看做现实中的过滤器,它负责将污水中的杂质过滤,从而使进入的污水变成净水。而对于Web应用程序来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器端之间的请求与响应信息。
作用:
执行时机:
在执行对应的Servlet之后.(过滤Respons对象中的内容)
发展历史
由于Servlet规范是开放的,借助于公众与开源社区的力量,Servlet规范越来越科学,功能也越来越强大。2000年,Sun公司在Servlet2.3规范中添加了Filter功能,并在Servlet2.4中对Filter进行了细节上的补充。目前主流版本为Servlet2.5的Filter。
Filter最早在Servlet 2.3版本提供
Filter在Servlet 2.5版本完善
运行原理
如何使用
Filter提供的方法:
* init()
* doFilter()
* destroy()
实现步骤:
* 创建Java类,实现Filter接口,并且重写所有方法.
* 在web.xml文件中进行配置.
<filter><filter-name>MyFilter1</filter-name><filter-class>app.java.filter.MyFilter1</filter-class> </filter> <filter-mapping><filter-name>MyFilter1</filter-name><url-pattern>/*</url-pattern> </filter-mapping>
生命周期
ServletAPI提供的Filter接口中含有三个方法,分别为init()、doFilter()和destroy()方法。该三个方式就是Filter的生命周期方法。
Filter的构造函数
在Tomcat服务器启动时执行。
在Filter的生命周期中只执行一次。
init(FilterConfig)方法
在Tomcat服务器启动时执行。
在Filter的生命周期中只执行一次。
用于Filter的初始化工作。
doFilter(ServletRequest,ServletResponse, FilterChain)方法
在每次拦截时执行。
在Filter的生命周期中只执行多次。
用于Filter的拦截处理工作。
destroy()方法
在Tomcat服务器关闭时执行。
在Filter的生命周期中只执行一次。
用于Filter的销毁工作。
package app.java.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;/** * 自定义过滤器: * * 实现Filter接口,并且重写该接口提供所有的方法. * @author JYL * */public class MyFilter1 implements Filter {/** * Filter的构造函数: * * 执行时机:在Tomcat服务器启动时. * * 执行次数:在Filter的生命周期中只执行一次. * * Filter与Servlet一样,都是单例多线程的.(线程安全问题) */public MyFilter1() {System.out.println("这是MyFilter1的构造函数...");}/** * init(FilterConfig config)方法: * * 作用:用于过滤器的初始化. * * 执行时机:在Tomcat服务器启动时. * * 执行次数:在Filter的生命周期中只执行一次. */public void init(FilterConfig config) throws ServletException {System.out.println("这是MyFilter1的init()方法...");}/** * doFilter(ServletRequest request, ServletResponse response,FilterChain chain)方法: * * 作用:用于过滤器的过滤. * * 执行时机:客户端访问当前Filter拦截的资源路径时. * * 执行次数:在Filter的生命周期中,每次拦截,每次执行. */public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("这是MyFilter1的doFilter()方法...");//过滤器的放行chain.doFilter(request, response);}/** * destroy()方法: * * 作用:用于过滤器的销毁. * * 执行时机:在Tomcat服务器关闭时. * * 执行次数:在Filter的生命周期中只执行一次. */public void destroy() {System.out.println("这是MyFilter1的destroy()方法...");}}
扩展:
* 面向对象:这个人就是对象,年龄、性别等是属性,出生、上学、结婚等方法.
* 类与对象的区别:
* 类:比作女生.
* 对象:就是范冰冰.
* 实现、继承、多态、封装等概念.
* 面向过程:这个人从出生,长大、上学、工作、...、去世.
过滤器链
* 如何定义过滤器被执行的先后顺序?(创建方法的执行不分顺序)
* Filter的doFilter()方法具有一个参数FilterChain,通过调用chain.doFilter()方法可以放行.
* 在过滤器链中,执行chain.doFilter()方法,是否还是放行的作用?
* 如果是,应该被放行到哪里去了?(单个Filter时,直接被放行到对应的Web资源[Servlet、JSP])
* 解决以上问题:
* chain.doFilter()方法依旧是放行方法.
* 如果执行的不是过滤器链中最后一个过滤器的话,执行chain.doFilter()方法,会被放行到下一个过滤器里.
* 如果执行的是过滤器链中最后一个过滤器的话,chain.doFilter()方法,才会被放行到对应Web资源中.
* 过滤器链中的过滤器执行的先后顺序由web.xml文件中的<filter-mapping>标签定义的先后顺序决定.
* 实际开发的意义:
* 单个Filter完成单个任务.
FilterChain的doFilter()方法执行时,如果只有一个过滤器的话,执行该方法会将请求发送给服务器端的动态或静态资源。如果是过滤器链的话,只有在执行过滤器链的最后一个过滤器的FilterChain的doFilter()方法时,才会将请求发送给服务器端的动态或静态资源。如果不是在过滤器链的最后一个过滤器的FilterChain的doFilter()方法时,将请求发送给下一个过滤器进行拦截。
在过滤器链中的过滤器执行的先后顺序是按照Web工程的web.xml文件配置过滤器的先后顺序被执行。
FilterConfig
在web.xml文件中是如何配置的:
<filter><filter-name>MyFilter2</filter-name><filter-class>app.java.filter.MyFilter2</filter-class><init-param><param-name>mingjiao</param-name><param-value>zhangwuji</param-value></init-param></filter>FilterConfig的用法与ServletConfig一致.
需要注意的是,通过getInitParameter()方法获取的初始化参数是私有参数。只有当前过滤器才能获取到,而其他过滤器并不能访问。如果配置全局初始化参数,可以使用<context-param>来配置,并使用ServletContext对象获取。
* 目录匹配:/aaaa/
* 扩展名匹配:*.do
* 优先级别:完全匹配 -> 目录匹配 -> 扩展名匹配
* 如果当前Filter拦截对应Servlet的话:
* 还可以使用<servlet-name>标签
<filter> <filter-name>MyFilter2</filter-name> <filter-class>app.java.filter.MyFilter2</filter-class> <init-param> <param-name>mingjiao</param-name> <param-value>zhangwuji</param-value> </init-param></filter><filter-mapping> <filter-name>MyFilter2</filter-name> <servlet-name>MyServlet2</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher></filter-mapping>
* Filter拦截Servlet默认情况是拦截直接请求.
* 在web.xml文件中配置<filter-mapping>标签中具有<dispatcher>
* <dispatcher>标签在同一个Filter的配置中,可以配置多个.
* <dispatcher>标签的值:
* REQUEST:是默认值,表示一次请求. 表示仅当直接请求Servlet时才生效。
* FORWARD:表示请求转发到. 表示仅当某Servlet通过FORWARD到该Servlet时才生效。
* INCLUDE:表示包含(例如JSP包含另一个JSP等) JSP中可以通过<jsp:include>标签请求某Servlet或调用RequestDispatcher的include()方法请求某Servlet,仅这种情况下有效。
* ERROR:表示JSP的<%@ page errorPage=""%> JSP中可以通过<%@ pageerrorPage=”error.jsp”>标签指定错误处理页面,仅这种情况下有效。
<url-pattern>标签与<dispatcher>标签的关系是“且”的关系。只有满足<url-pattern>标签的条件,且满足<dispatcher>标签的条件时,当前过滤器才能生效。
package app.java.filter; import java.io.IOException;import java.util.Enumeration;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public class MyFilter2 implements Filter {public void destroy() {}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("这是MyFilter2的doFilter()方法...");chain.doFilter(request, response);}public void init(FilterConfig config) throws ServletException {System.out.println("这是MyFilter2的init()方法...");Enumeration enums = config.getInitParameterNames();while (enums.hasMoreElements()) {String name = (String) enums.nextElement();String value = config.getInitParameter(name);System.out.println(name+" : "+value);}}}MyServlet1:
package app.java.servlet;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 MyServlet1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.getRequestDispatcher("/servlet2").forward(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
package app.java.servlet;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 MyServlet2 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("这是Servlet2.........");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 过滤器
- 增强版ListView-RecyclerView
- SpringBoot学习系列基础Demo Mysql数据库
- [leetcode]29. Divide Two Integers
- 转载-----IIC协议及其对ACK应答信号的处理
- 深度学习菜鸟的信仰地︱Supervessel超能云服务器、深度学习环境全配置
- 过滤器
- 常用正則表達式
- Tomcat修改80端口的一系列问题
- linux centos下mysql数据库的主从复制环境搭建
- Properties文件操作
- opencv学习笔记(十八)cvSplit()、cvMerge()彩色图片通道分割与融合
- 你必须收藏的 GitHub 技巧
- Ubuntu16.04软件中心闪退
- linux awk简介