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)
import javax.servlet.*;
import java.io.IOException;public class MyFilter implements Filter {}
- 2.2 重写
doFilter
,实现过滤逻辑,酌情放行
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 {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 获取访问的IPHttpServletRequest 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
注解,实现过滤的范围配置
import javax.servlet.annotation.WebFilter;/*** 自定义过滤器:实现根据IP统计访问次数*/
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 放行filterChain.doFilter(servletRequest, servletResponse);}
}
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
接口
import org.springframework.web.servlet.HandlerInterceptor;public class MyInterceptor implements HandlerInterceptor {}
- 3.2 实现接口中的拦截方法(
preHandle
-请求执行前、postHandler
-请求执行后、afterCompletion
-视图渲染后)
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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 记录访问IP的次数逻辑// 获取访问的IPString 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
方法
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;public class InterceptorConfiguration implements WebMvcConfigurer {@Overridepublic 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。