大家好,欢迎来到IT知识分享网。
目录
在 Web 应用中,可以部署多个 Filter,若这些 Filter 都拦截同一目标资源,则它们就组成了一个 Filter 链(也称过滤器链)。过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求在这些过滤器之间传递,直到传递给目标资源。
FilterChain 接口
javax.servlet 包中提供了一个 FilterChain 接口,该接口由容器实现。容器将其实例对象作为参数传入 Filter 对象的 doFilter() 方法中。Filter 对象可以使用 FilterChain 对象调用链中下一个 Filter 的 doFilter() 方法,若该 Filter 是链中最后一个过滤器,则调用目标资源的 service() 方法。FilterChain 接口中只有一个方法,如下表。
返回值类型 | 方法 | 描述 |
---|---|---|
void | doFilter(ServletRequest request ,ServletResponse response) | 使用该方法可以调用过滤器链中的下一个 Filter 的 doFilter() 方法,若该 Filter 是链中最后一个过滤器,则调用目标资源的 service() 方法。 |
在 Filter.doFilter() 方法中调用 FilterChain.doFilter() 方法的语句前后增加某些程序代码,就可以在 Servlet 进行响应前后实现某些特殊功能,例如权限控制、过滤敏感词、设置统一编码格式等。
Filter 链的拦截过程
Filter 链的拦截过程如下图所示。
请求资源时,过滤器链中的过滤器依次对请求进行处理,并将请求传递给下一个过滤器,直到最后将请求传递给目标资源。发送响应信息时,则按照相反的顺序对响应进行处理,直到将响应返回给客户端。
过滤器并不是必须要将请求传递到下一个过滤器或目标资源,它可以自行对请求进行处理,并发送响应给客户端,也可以将请求转发给其他的目标资源。// 可以直接返回资源,不再往后传递
注:过滤器链中的任何一个 Filter 没有调用 FilterChain.doFilter() 方法,请求都不会到达目标资源。
Filter 链中 Filter 的执行顺序
通过 web.xml 配置的 Filter 过滤器,执行顺序由 <filter-mapping> 标签的配置顺序决定。<filter-mapping> 靠前,则 Filter 先执行,靠后则后执行。通过修改 <filter-mapping> 的顺序便可以修改 Filter 的执行顺序。
通过 @WebFilter 注解配置的 Filter 过滤器,无法进行排序,若需要对 Filter 过滤器进行排序,建议使用 web.xml 进行配置。// 但如果需要,修改filter目录中对应过滤器的文件名按首字母顺序调整自己想要的顺序即可!!!
示例
创建名称为 LoginServlet 的类,代码如下。
package swadian.servlet.filter;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author swadian
* @date 2022/2/14
* @Version 1.0
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public LoginServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
//设置向页面输出的格式与编码
response.getWriter().write("<h3>LoginServlet 欢迎您 !</h3>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
doGet(request, response);
}
}
创建名称为 FirstChainFilter 的类,代码如下。
package swadian.servlet.filter;
import javax.servlet.DispatcherType;
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;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author swadian
* @date 2022/2/14
* @Version 1.0
*/
@WebFilter(dispatcherTypes = {
DispatcherType.REQUEST,
DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.ERROR
},
urlPatterns = {"/LoginServlet"})
public class FirstChainFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//设置向页面输出的格式与编码
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.write("FirstChainFilter 对请求进行处理<br/>");
chain.doFilter(request, response);
writer.write("FirstChainFilter 对响应进行处理<br/>");
}
@Override
public void destroy() {
}
}
创建名称为 SecondChainFilter 的类,代码如下。
package swadian.servlet.filter;
import javax.servlet.DispatcherType;
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;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author swadian
* @date 2022/2/15
* @Version 1.0
*/
@WebFilter(dispatcherTypes = {
DispatcherType.REQUEST,
DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.ERROR
},
urlPatterns = {"/LoginServlet"})
public class SecondChainFilter implements Filter {
public SecondChainFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//设置向页面输出的格式与编码
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.write("SecondChainFilter 对请求进行处理<br/>");
chain.doFilter(request, response);
writer.write("SecondChainFilter 对响应进行处理<br/>");
}
public void init(FilterConfig fConfig) {
}
}
启动 Tomcat 服务器,在浏览器地址栏中输入“http://localhost:8080/web/LoginServlet”,结果如下。
附:web.xml 中配置过滤器方式
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!--过滤器链中FirstChainFilter配置 -->
<filter>
<filter-name>FirstChainFilter</filter-name>
<filter-class>swadian.servlet.filter.FirstChainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FirstChainFilter</filter-name>
<url-pattern>/LoginServlet</url-pattern>
</filter-mapping>
<!--过滤器链中SecondChainFilter配置 -->
<filter>
<filter-name>SecondChainFilter</filter-name>
<filter-class>swadian.servlet.filter.SecondChainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecondChainFilter</filter-name>
<url-pattern>/LoginServlet</url-pattern>
</filter-mapping>
</web-app>
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11925.html