Servlet过滤器的作用:
- 查询请求并做出相应的动作
- 阻塞请求-响应时,使其不能下一步行动发
- 修改请求的头部和数据,用户可以提供自定义的请求
- 修改相应的头部和数据,用户可以通过定制的相应版本实现
- 与外部资源进行交互
Servlet对请求的过滤过程:
- Servlet创建一个过滤器实例
- 过滤器实例调用init方法,读取过滤器的初始化参数
- 过滤器实例调用doFilter方法,根据初始化参数的值判断该请求是否合法,如果请求不合法,则阻塞该请求;如果请求合法,则调用chain.doFilter方法将该请求向后传递
Servlet对响应的过滤过程:
- 过滤器截获客户端的请求
- 重新封装ServletResponse,在封装后的ServletResponse中提供用户自定义的输出流
- 将请求向后续传递
- Web组件产生响应
- 从封装后的ServletResponse中获取用户自定义的输出流
- 将响应内容通过用户自定义的输出流写到缓冲流中
- 在缓冲流中修改响应的内容后清空缓冲流,输出响应内容
Servlet过滤器接口的构成:
- init(FilterConfig):Servlet 过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。
这个方法中可以读取web.xml文件中Servlet过滤器的初始化参数 - doFilter(ServletRequest,ServletResponse,FilterChain):用于完成实际的过滤操作
当用户请求访问URL时,Serlet容器将先调用doFilter方法,FilterChain方法访问后续过滤器 - destroy():Servlet容器在取消过滤器实例前调用的方法,用来释放Servlet过滤器占用的资源
Servlet过滤器的创建步骤
- 建立一个实现Javax.servlet.Filter接口的类。 这个类需要三种方法,分别是doFilter、init、和destroy。
doFilter方法包含主要的过滤代码,在init方法中进行一些初始化的设置,在destroy清除过滤器占用的资源 - 实现init方法,读取过滤器的初始化函数、
- 实现doFilter方法完成对过滤器的响应。doFilter方法的第一个参数是ServletRequest对象。此对象给过滤器提供了对进入的信息的完全访问。第二个参数为ServletResponse,通常再简单的过滤器中忽略该参数。最后一个参数为FilterChain,如下一步所诉,此参数用来调用过滤器中下一个过滤器或者在到达过滤器末尾是时调用Servlet或JSP页
- 调用FilterChain接口对象的doFilter方法,向后续的过滤器传递响应或请求。
Filter接口的doFilter方法把一个FilterChain对象作为它的一个参数。
在调用此对象的doFilter方法时,激活下一个相关的过滤器。 - 对相应的的Servlet和JSP页面注册过滤器。在部署描述符文件(Web.xml)中使用Filter和filter-mapping元素对需要过滤的资源进行配置
同时也可以用@WebFilter注解或部署描述文件定义过滤器
监听器类实现:
package bean;
import javax.servlet.*;
import java.io.*;
public class CopyrightFilter implements Filter {
protected FilterConfig config;
protected String date;
public void init(FilterConfig filterconfig)throws ServletException{
this.config = filterconfig;
date = filterconfig.getInitParameter("date");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
PrintWriter out = response.getWriter();
out.println("<br><center><font color='red'>Web监听器测试,下面是监听器添加的时间"
+ "</font></center>");
if(date!=null){
out.println("<br><center><font color='red'>"+date+"</font></center>");
out.flush();
}
}
public void destroy(){
this.config=null;
}
}
对Filter进行相应配置:
<filter>
<filter-name>CopyrightFilter</filter-name>
<filter-class>bean.CopyrightFilter</filter-class>
<init-param>
<param-name>date</param-name>
<param-value>2018.9</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CopyrightFilter</filter-name>
<url-pattern>/HelloJFilterTestSP.jsp</url-pattern>
</filter-mapping>
上述代码加在web.xml文件中,配置了一个监听器并且还配置了详细的路径对一个jsp文件进行监听实现在下面增加两行内容,filter和filter-mapping元素对编写的Filter类进行注册并设置它所能拦截的资源,filter-mapping可以时具体的某个文件路径,也可以用/*表示。
编写一个JSP文件进行测试
<%@ page language="java" contentType="text/html; charset=utf8"
pageEncoding="utf8"%>
<%@ page import="java.util.*" %>
<!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>Filter监听器监听的页面</title>
</head>
<body>
<center>
<%
out.println("Filter测试"+"<br>");
%>
</center>
</body>
</html>
运行项目,在浏览器中输入http://localhost:8080/TomTest/HelloJSP.jsp,看到底下已经出现动态增加的属性值
并且只有在访问这个JSP文件路径时才会进行拦截修改。