什么是过滤器
生活中的过滤器场景:
什么是Web过滤器
Web过滤器过滤用户请求,但是不处理结果。
过滤器包括:过滤源,过滤规则和过滤结果。
过滤器的概念
过滤器是一个服务器端的组件,它可以截取客户端的请求与响应信息,并对这些信息过滤。
过滤器的工作原理
假设我们访问Web资源时:
1)没有过滤器的情况下:
2)存在过滤器的情况下:
过滤器的工作原理:
过滤器拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。
过滤器只能针对用户的请求进行服务器端跳转,不直接返回数据,因为过滤器不是一个标准的servlet页面。
过滤器是在Java Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和修改。
过滤器本身并不产生请求和响应对象,它只能提供过滤作用。过滤器能够在Servlet被调用之前检查Request
对象,修改Request Header和Request内容;在Servlet被调用之后检查Response对象,修改Response Header和
Response内容。
过滤器负责过滤的Web组件可以是Servlet、JSP或者HTML文件。
过滤器的作用
1过滤器会在一组资源的前面执行;
2过滤器可以让请求得到目标资源,也可以不让请求达到;
3过滤器有拦截请求的能力
过滤器的生命周期
过滤器的生命周期包含:
实例化——web.xml或注解
初始化——init()
过滤——doFilter()
销毁——destroy()
Filter的三个重要的方法是:
init()方法
init()方法是过滤器的初始化方法,Web容器创建过滤器实例后将调用这个方法,这个方法中可以读取web.xml文
件中过滤器的参数。
doFilter()方法
doFilter()方法完成实际的过滤操作,这个地方发是过滤器的核心方法,当用户请求访问与过滤器关联的URL时,
Web容器将先调用过滤器的doFilter()方法。FilterChain参数可以调用chain.doFilter()方法,将请求传给下一个过滤
器(或目标资源),或利用转发,重定向将请求转发到其他资源。
destroy()方法
destroy()方法是Web容器在销毁过滤器实例前调用的,在这个方法中可以释放过滤器占用的资源,大多数情况用
不到。
关于web.xml配置
过滤器是否能改变用户请求的Web资源?也就是能否改变用户请求的路径?可以
过滤器能否直接返回数据,能不能直接处理用户请求?不可以
使用注解制作第一个过滤器
过滤器如何编写:
1写一个类实现Filter接口
2在web.xml中进行配置或者使用注解。
代码实现
FirstFilter.java源代码:
package com.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; import javax.servlet.annotation.WebFilter; /** * Servlet Filter implementation class FirstFilter */ @WebFilter(filterName="FirstFilter",urlPatterns={"/index.jsp"}) public class FirstFilter implements Filter { /** * Default constructor. */ public FirstFilter() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub System.out.println("destroy------FirstFilter"); } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub // place your code here System.out.println("start------FirstFilter"); // pass the request along the filter chain chain.doFilter(request, response); System.out.println("end------FirstFilter"); } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub System.out.println("init------FirstFilter"); } }
index.jsp页面代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>过滤器</h1> <hr> <% System.out.println("处理过程完成"); %> </body> </html>
运行结果:
destroy()方法在服务器关闭之前销毁。
过滤器链
Web项目支持多个过滤器。
FilterChain.doFilter()方法
这个方法是执行目标资源,或是执行下一个过滤器,如果没有下一个过滤器那么执行的就是目标资源,如果有,
那么执行下一个过滤器。
多个过滤器的执行顺序:
web.xml配置文件的<filter-mapping>的配置顺序决定了过滤器的执行顺序。
注解中的顺序是难以控制的,在给Filter命名的时候注意名字首字母的顺序,这一般是执行的顺序的依据。
过滤器链
过滤器示意图:
执行过程:
代码实现
在第一个过滤器的基础上我们再增加第二个过滤器对同一页面进行过滤操作。
SecondFilter.java源代码:
package com.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; import javax.servlet.annotation.WebFilter; /** * Servlet Filter implementation class SecondFilter */ @WebFilter(filterName="SecondFilter",urlPatterns={"/index.jsp"}) public class SecondFilter implements Filter { /** * Default constructor. */ public SecondFilter() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub System.out.println("destroy------SecondFilter"); } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub // place your code here System.out.println("start------SecondFilter"); // pass the request along the filter chain chain.doFilter(request, response); System.out.println("end------SecondFilter"); } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub System.out.println("init------SecondFilter"); } }
执行结果:
销毁方法同样在关闭服务器之前执行。