过滤器七:过滤链

目录

一:过滤链简介

二:过滤链案例

三:第一个需要注意的问题:chain.dofilter()书写位置    与    请求和响应过程中执行的关系

补:控制过滤链中断:阻挡请求(一种简单的防火墙)

四:第二个需要注意的问题:注解形式时,过滤器执行的顺序(仅供了解,因为在实际工作中基本不会采用这种策略)


一:过滤链简介

如下图,过滤器1,过滤器2,Servlet这三者组成了一个完整的过滤链。

注意事项:即chain.doFilter()向后传递的时候是根据web.xml中<filter-mapping>的书写顺序为依据的;


二:过滤链案例

案例:包括,FilterA,FilterB,FilterC三个过滤器,web.xml配置文件,HelloServlet这个Servlet:

扫描二维码关注公众号,回复: 12756358 查看本文章

web.xml:循规蹈矩的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>filter-chain</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>
  	<filter-name>filterAA</filter-name>
  	<filter-class>com.imooc.filter.FilterA</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filterAA</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <filter>
  	<filter-name>filterBB</filter-name>
  	<filter-class>com.imooc.filter.FilterB</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filterBB</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <filter>
  	<filter-name>filterCC</filter-name>
  	<filter-class>com.imooc.filter.FilterC</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>filterCC</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

HelloServlet.java:这个Servlet不是本篇博客的重点啦

package com.imooc.filter;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloServlet
 */
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().println("hello world!");
		System.out.println("hello nihao!!!");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

启动应用后,访问localhost:8080/filter-chain/hello:浏览器页面可以显示HelloServlet返回的内容,这个很简单;

同时,在控制台:按照在web.xml中<filter-mapping>的书写顺序,依次执行三个过滤器;当执行到过滤器C的时候,接下来没有过滤器了,就将请求传递到HelloServlet;


三:第一个需要注意的问题:chain.dofilter()书写位置    与    请求和响应过程中执行的关系

但是如果把FilterA,FilterB,FilterC三个过滤器的chain.doFilter()都写在前面:

此时启动应用,访问localhost:8080/filter-chain/hello时候:

原因解释:FilterA,FilterB,FilterC这三个过滤器的doFilter()方法中,chain.doFilter()都放在了前面,这意思就是,当请求过来的时候,这个过滤器会执行chain.doFilter()方法,当执行到chain.doFilter()这条语句的时候,就会把请求传递给下一个过滤器了,这样从FilterA传到FilterB,从FilterB传到FilterC,控制台就依次打印了A!,B!和C!;一直传给了HelloServlet,输出“hello nihao!!!”;

然后,当响应的时候,按照反方向,依次执行FilterC中的doFilter()方法中的chain.doFilter()语句后面的内容,然后是FilterB,然后是FilterA;这样,控制塔就依次打印出了This is Filter C! ;This is Filter B! 和 This is Filter A!;(注解,这个仅仅在这儿ok,并没有经过多次验证哎,但大概率应该是没问题的~~~


补:控制过滤链中断:阻挡请求(一种简单的防火墙)

启动应用:

这种在程序中刻意控制chain.doFilter()方法调用的场景是比较常见的;比如:互联网安全是非常重要的,比如,开发的网站只对中国的IP开发,外国的IP不能访问,怎么做呐?

可以获取请求的IP,如果IP是中国的,就去调用chain.doFilter()方法,将请求放行;如果IP是外国的,就通过if else判断,不去执行chain.doFilter()这句话,中断请求,从而这个IP为外国的请求就被过滤器挡在了外面;(这也是简单的一种防火墙)


四:第二个需要注意的问题:注解形式时,过滤器执行的顺序(仅供了解,因为在实际工作中基本不会采用这种策略)

关于过滤器的执行顺序:(1)当过滤器采用web.xml配置的方式的时候,按照在web.xml中<filter-mapping>的书写顺序,来依次执行;(2)过滤器采用注解的时候,过滤器的执行顺序怎么确定呐???

如下:

启动应用,访问localhost:8080/filter-chain/hello:

其实当过滤器采用注解的形式的时候:其按照类名来决定前后顺序的,按照字母升序,从小到大,且字母不区分大小写;所以先执行FilterA,然后执行FilterB,最后执行FilterC;

如,把FilterA过滤器类的类名改成FilterZ时:再次访问的时候:

猜你喜欢

转载自blog.csdn.net/csucsgoat/article/details/114289581