过滤器、拦截器简单流程及使用

前言

今天咱们来复习一下过滤器与拦截器吧,这是每一个Java程序员都要求掌握的技术,不许说不会哦,不会就赶紧学习,嘿嘿,咱们抓紧时间,现在就开始吧

image

1. 过滤器与拦截器的差异

过滤器和拦截器在功能上接近,但是他们有很大区别

1.过滤器可以修改request,而拦截器不能

2.过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境

3.过滤器不能调用IOC容器中的各种依赖,而拦截器可以

4.过滤器只能在请求的前后使用,而拦截器可以详细到每个方法

在这里插入图片描述

2. 过滤器的作用描述

在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest。

根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。

在HttpServletResponse 到达客户端之前,拦截HttpServletResponse。

根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。

2.1 过滤器实现

要想使用Filter,需要写一个方法继承Filter类,我们写如下两个自己的Filter类,首先是FirstFilter类,其中@Order里边的数字越小代表越先被该Filter过滤,@WebFilter代表这是个Filter类并把这个类注入到容器中:

package com.example.executor_test.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;
 
import org.springframework.core.annotation.Order;
 
@Order(1)
@WebFilter(filterName="firstFilter", urlPatterns="/*")
public class FirstFilter implements Filter {
 
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}
 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("first filter 1");
		chain.doFilter(request, response);
		System.out.println("first filter 2");
	}
 
	@Override
	public void destroy() {
		
	}
}

然后是第二个Filter,SecondFilter类

package com.example.executor_test.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;
 
import org.springframework.core.annotation.Order;
 
@Order(2)
@WebFilter(filterName="secondFilter", urlPatterns="/*")
public class SecondFilter implements Filter {
 
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
 
	}
 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("second filter 1");
		System.out.println("before:response" );
		chain.doFilter(request, response);
		System.out.println("after:response" );
		System.out.println("second filter 2");
		
	}
 
	@Override
	public void destroy() {
		
	}
}

然后我们把Controller类也写出来吧:

package com.example.executor_test.controller;
 
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
 
import javax.annotation.Resource;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
import com.example.executor_test.task.OldTask;
import com.example.executor_test.task.OldTaskThread;
 
@RestController
public class TestController {
	
	@GetMapping("/test1")
	public String test1() {
		System.out.println("method in controller");
		return "test1";
	}
 
}

最后是springboot的主方法入口,注意,由于我们使用注解注入的Filter,所以要在下边这个Application类中加入@ServletComponentScan注解:

package com.example.executor_test;
 
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ConfigurableApplicationContext;
 
import com.example.executor_test.task.OldTaskThread;
 
@SpringBootApplication
@ServletComponentScan
public class ExecutorTestApplication {
 
	public static void main(String[] args) {	
		ConfigurableApplicationContext applicationContext = SpringApplication.run(ExecutorTestApplication.class, args);
	}
}

首先我们先来看一下执行结果,启动后访问127.0.0.1:8080/test1,在后台中打印如下信息:

first filter 1
second filter 1
before:response
method in controller
after:response
second filter 2
first filter 2

1.我们可以看出代码执行的流程,首先请求被firstfilter截获,打印出first filter 1

2.然后去执行chain.doFilter(request, response),这句话代表着请求会转发给过滤器链上下一个对象,也就是secondfilter,所以打印出secondfilter里的second filter 1

3.接下来再执行secondfilter里的chain.dofilter()方法,请求再转发给下一个对象,由于没有其他的filter了,所以会转发给controller,打印出了controller类中的method in controller

4.接下来再去内存栈里调用secondfilter的print(“second filter 2”),然后再去内存栈里调用firstfilter的print(“first filter 1”)

所以如果在自己实现的Filter类的doFilter方法里不加chain.doFilter(req, rep)是万万不行的,那样会导致请求到了这个filter里就不再往下走,永远进不了controller中

猜你喜欢

转载自blog.csdn.net/qq_49313444/article/details/107504196