1.过滤器和拦截器简述
过滤器Filter和拦截器Interceptor, 在功能方面很类似, 但在具体实现方面差距还是比较大。
- 1.1 运行顺序不同:
Filter
→Servlet
→Interceptor
→Controller
; - 1.2 配置方式不同:
Filter
在web.xml
中进行配置,Interceptor
在Spring的配置文件
中进行配置(或注解); - 1.3 依赖环境不同:
Filter
依赖于Servlet容器,而Interceptor
不依赖Servlet容器; - 1.4 操作对象不同:
Filter
只能对request
和response
进行操作,而Interceptor可对request
、response
、handler
、modelAndView
、exception
进行操作(对Spring MVC生态下组件的操作能力)。
2.过滤器的配置
- 2.1 自定义过滤器,实现
Filter
接口(Springboot3开始,jakarta.servlet.Filter)
java
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
}
- 2.2 重写
doFilter
,实现过滤逻辑,酌情放行
java
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;
/**
* 自定义过滤器:实现根据IP统计访问次数
*/
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 获取访问的IP
HttpServletRequest request = (HttpServletRequest) servletRequest;
String ip = request.getRemoteAddr();
// 统计访问次数并输出
HttpSession session = request.getSession();
Integer count = (Integer) session.getAttribute("count");
count = Objects.isNull(count) ? 1 : ++count;
System.out.println("ip:" + ip + "\tcount:" + count);
session.setAttribute("count", count);
// 放行
filterChain.doFilter(servletRequest, servletResponse);
}
}
- 2.3 添加
@WebFilter
和@ServletComponentScan
注解,实现过滤的范围配置
java
import javax.servlet.annotation.WebFilter;
/**
* 自定义过滤器:实现根据IP统计访问次数
*/
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 放行
filterChain.doFilter(servletRequest, servletResponse);
}
}
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan(basePackages = "com.neusoft.springboot.filter")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3.拦截器的配置
- 3.1 自定义拦截器,实现
HandlerInterceptor
接口
java
import org.springframework.web.servlet.HandlerInterceptor;
public class MyInterceptor implements HandlerInterceptor {
}
- 3.2 实现接口中的拦截方法(
preHandle
-请求执行前、postHandler
-请求执行后、afterCompletion
-视图渲染后)
java
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 记录访问IP的次数逻辑
// 获取访问的IP
String ip = request.getRemoteAddr();
// 统计访问次数并输出
HttpSession session = request.getSession();
Integer count = (Integer) session.getAttribute("count");
count = Objects.isNull(count) ? 1 : ++count;
System.out.println("ip:" + ip + "\tcount:" + count);
session.setAttribute("count", count);
// 放行
return true;
}
}
- 3.3 创建配置类,实现
WebMvcConfigurer
接口,重写addInterceptors
方法
java
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class InterceptorConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
MyInterceptor myInterceptor = new MyInterceptor();
registry.addInterceptor(myInterceptor).addPathPatterns("/*");
}
}
4.总结
- 4.1 Filter依赖于Servlet容器,属于Servlet规范的一部分,而Interceptor依赖于SpringMVC框架;
- 4.2 Filter的生命周期由Servlet容器管理,而Interceptor通过IOC容器来管理,可通过注入等方式来获取其Bean的实例;
- 4.3 Filter可拦截所有Web资源(包括jsp,servlet,静态资源),而Interceptor则只拦截Controller。