1.Filter简介
Filter中文意思为过滤器。顾名思义,过滤器可在浏览器以及目标资源之间起到一个过滤的作用。例如:水净化器,可以看成是生活中的一个过滤器,他可以将污水中的杂质过滤,从而使进入的污水变成净水。
对于WEB应用来说,过滤器是一个驻留在服务器中的WEB组件,他可以截取客户端和WEB资源之间的请求和响应信息,WEB资源可能包括Servlet、JSP、HTML页面等。
2. Filter 的 HelloWorld
(1) 实际上 Filter 是一个接口。
(2) 具体步骤
① 创建一个类, 实现 Filter 接口
② 在 web.xml 文件中配置使用 Filter
<filter>
<filter-name>Filter的别名</filter-name>
<filter-class>filter的全类名</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter的别名</filter-name>
<url-pattern>要拦截的请求的地址</url-pattern>
</filter-mapping>
(3) 代码实现
① 创建一个类, 实现 Filter 接口
public class HelloWorldFilter implements Filter {
//在 Filter 被创建后, Servlet 容器立即调用的初始化方法. 只被调用一次,类似于 Servlet 的 init 方法.
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("init...");
String name = config.getInitParameter("name");
System.out.println("name:" + name);
}
//实际上 Filter 工作时调用的方法. 类似于 Servlet 的 service 方法.
//FilterChain: Filter 链.
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("doFilter...");
//若需要相应目标资源: 请求的是什么就响应什么. 即: 放行. 此时需要调用 FilterChain 的 doFilter 方法,将把请求给下一个拦截器或目标资源.
//chain.doFilter(request, response);
//若不能响应目标资源. 可以利用 request 的转发响应其他的页面. 或 response 的重定向响应其他页面. 但此时不能再调用 chain 的 doFilter 方法.
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
//在 Filter 被销毁之前调用的方法. 只被调用一次. 类似于 Servlet 的 destroy
@Override
public void destroy() {
System.out.println("destroy...");
}
}
② 在 web.xml 文件中配置使用 Filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Filter</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置 Filter. 和配置 Servlet 几乎一致 -->
<filter>
<filter-name>helloworld</filter-name>
<filter-class>com.atguigu.javaweb.filters.HelloWorldFilter</filter-class>
<!-- 配置初始化参数. 和配置 Servlet 的初始化参数一致 -->
<init-param>
<param-name>name</param-name>
<param-value>guigu</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>helloworld</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
③ 请求页面
<%@ 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>
<h4>Index Page</h4>
<a href="helloworld.jsp">Hello World Page</a>
</body>
</html>
3.Filter 的 API
(1) init 方法中的 FilterConfig: 类似于 Servlet 的 init 方法中的 ServletConfig。
主要用于获取当前 Filter 在 web.xml 文件中配置的初始化参数。
(2) doFilter 方法中的 FilterChain: 代表 Filter 链. 只有一个方法: doFilter。
若还有下一个 Filter, 则将把请求传递给下一个 Filter
若当前 Filter 是最后一个 Filter, 则将调用目标资源
4.
Filter
生命周期
和 Servlet 一致, Filter的生命周期是Filter由被创建到被销毁的过程 。
(1) Filter 是单例的
(2) Filter的生命周期
① 构造器:服务器一启动就会创建Filter的实例,只会调用一次,Filter是单例。
② init(): 构造器调用之后,马上调用,用来初始化Filter,只会调用一次。
FilterConfig:代表当前Filter的配置信息,可以获取当前Filter的初始化参数,还可以获ServletContext对象。
③ doFilter():每次拦截请求时都会调用,会调用多次。
ServletRequest:代表浏览器发送给服务器的请求报文,和Servlet中的request是一样的。
ServletResponse:代表的是服务器响应给浏览器的响应报文,和Servlet中的response是一样的。
FilterChain: 用来放行请求:
chain.doFilter(request,response) --> 放行请求,当调用该方法时,相当于调用了目标资源的service方法。
④ destroy():项目卸载Filter对象销毁前调用,用来做一些如释放资源等收尾的工作,只会调用一次。
5.多个 Filter 时, 方法的调用顺序?
和在web.xml文件中的配置顺序有关,配置在前面的先执行。
6.配置 Filter 的拦截方式
默认情况下, Filte 只能拦截请求, 但不能拦截转发.可以通过在web.xml文件中配置解决
7.Filter 典型的使用场景:字符编码过滤器
我们只需要创建一个类继承Filter并且在web.xml文件中配置字符编码过滤器,然后在这个类里面的doFilter方法中设置request.setCharacterEncoding("utf-8");即可。