在Spring Boot项目中,拦截器(Interceptor)和过滤器(Filter)都是用来处理请求前后的逻辑,但它们在实现上有所不同,并且各自有一些特定的功能和用途。下面分别介绍这两种机制的区别和实现方法。
拦截器(Interceptor)
拦截器主要用于Spring MVC框架中,它们在控制器方法执行前后进行拦截操作。拦截器可以用来做一些通用的操作,例如日志记录、权限检查等。
实现方式
-
实现HandlerInterceptor接口
import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理之前执行 // 返回false表示不再继续处理该请求 return true; // 或者return false; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 请求处理之后执行,但是视图渲染之前 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 视图渲染之后执行 } }
-
配置拦截器
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()) .addPathPatterns("/**") // 指定拦截的路径 .excludePathPatterns("/login"); // 排除拦截的路径 } }
过滤器(Filter)
过滤器是在Servlet容器层面工作的,它们可以应用于任何类型的Servlet容器。过滤器的主要用途包括编码转换、权限验证、统计等。
实现方式
-
实现Filter接口
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 java.io.IOException; public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化过滤器 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 在请求处理之前执行 chain.doFilter(request, response); // 必须调用,否则请求无法继续传递 // 在请求处理之后执行 } @Override public void destroy() { // 清理资源 } }
-
配置过滤器
可以通过
web.xml
文件配置过滤器,但在Spring Boot中通常使用Java配置。import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebConfig { @Bean public FilterRegistrationBean<MyFilter> myFilterRegistration() { FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new MyFilter()); registration.addUrlPatterns("/*"); return registration; } }
区别总结
-
执行顺序:
- 过滤器先于拦截器执行。
- 过滤器在整个请求处理过程中都可以执行,而拦截器只在MVC层执行。
-
应用场景:
- 过滤器更适合做一些通用的预处理工作,如编码转换、添加请求头等。
- 拦截器更适合做与业务逻辑相关的操作,如权限验证等。
-
配置方式:
- 过滤器可以通过
web.xml
或Java配置来注册。 - 拦截器需要通过Spring的配置类来注册。
- 过滤器可以通过
-
生命周期:
- 过滤器有一个初始化方法
init
和销毁方法destroy
。 - 拦截器没有初始化和销毁的方法。
- 过滤器有一个初始化方法
-
获取Spring上下文中的bean:
- 过滤器不能直接获取Spring上下文中的bean,除非通过
ApplicationContext
注入。 - 拦截器可以通过构造函数或
@Autowired
注解来注入Spring管理的bean。
- 过滤器不能直接获取Spring上下文中的bean,除非通过