大家好,欢迎来到IT知识分享网。
拦截器(Interceptor)和过滤器(Filter)都是在Spring Boot中对于HTTP请求进行预处理和后处理的机制,但是它们在实现方式、使用场景和工作层级上有一些关键的区别。下面我们就来介绍一下具体的操作以及具体的实现示例。
过滤器(Filter)
过滤器是属于Servlet规范的一部分,其作用在Servlet容器(如 Tomcat)层面。通常情况下过滤器在Spring MVC的执行之前就会被触发,并且支持对原始的HTTP请求和响应进行处理或修改。一般被用来记录日志记录、进行安全认证、进行跨域请求处理等操作,Filter可以直接对请求和响应的流进行操作。
如下所示,过滤器是通过实现javax.servlet.Filter来对HTTP请求进行处理的,在javax.servlet.Filter中主要提供了如下的三个方法。
void init(FilterConfig filterConfig); void doFilter(ServletRequest request, ServletResponse response, FilterChain chain); void destroy();
分别表示初始化、执行、以及销毁。下面我们给出一个过滤器来出日志操作的功能实现,来一起看看过滤器如何实现并且使用。
假设我们需要对每个请求进行日志记录,如下所示。
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; import java.util.logging.Logger; public class LoggingFilter implements Filter { private final Logger logger = Logger.getLogger(LoggingFilter.class.getName()); @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化操作 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("Request received at " + request.getRemoteAddr()); chain.doFilter(request, response); // 继续传递请求到下一个过滤器或者目标资源 logger.info("Response sent"); } @Override public void destroy() { // 销毁操作 } }
在Spring Boot中,可以通过如下的配置来将其添加到容器中生效并且使用。
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.boot.web.servlet.FilterRegistrationBean; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean<LoggingFilter> loggingFilter() { FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new LoggingFilter()); registrationBean.addUrlPatterns("/api/*"); // 只对 /api 路径进行过滤 return registrationBean; } }
过滤器主要作用在请求进入Spring MVC之前,因此可以在请求和响应进入Spring之前对其进行过滤处理。
拦截器(Interceptor)
拦截器,则是属于Spring MVC框架的一部分,其主要作用在Spring MVC层面。在请求被路由到具体的Controller方法前和返回给客户端之前进行处理。典型使用场景主要有对用户权限校验、执行时间统计、在特定请求中修改数据模型等。
如下所示,拦截器的实现主要是基于HandlerInterceptor接口实现,该接口包括了如下的三个方法。
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler); void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView); void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
preHandle方法的返回值是一个布尔值,如果返回false,则表示请求不会被传递到下一个拦截器或者Controller方法,直接终止请求处理。
如下所示我们给出一个基于用户认证的拦截器的示例,如下所示,对每个请求进行用户认证拦截。
import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); if (token == null || !isValidToken(token)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; // 拦截请求,直接返回 401 未授权 } return true; // 继续请求,进入 Controller } private boolean isValidToken(String token) { // 简单的 token 验证逻辑 return "valid-token".equals(token); } }
在SpringBoot中拦截器需要在WebMvcConfigurer中进行配置,如下所示。
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 AuthInterceptor()) .addPathPatterns("/secure/*"); // 只对 /secure 路径进行拦截 } }
总结对比
比较点 |
过滤器(Filter) |
拦截器(Interceptor) |
层级 |
Servlet 容器层面 |
Spring MVC 层面 |
执行时机 |
DispatcherServlet 之前 |
DispatcherServlet 之后,Controller 方法之前和之后 |
适用场景 |
跨域、日志、编码转换、请求/响应的过滤等 |
用户认证、授权、日志、执行时间分析等 |
接口 |
javax.servlet.Filter |
HandlerInterceptor |
影响返回值 |
无,必须调用 chain.doFilter() 继续执行 |
有, preHandle 返回 false 时会中断请求 |
通过这两个详细的例子,可以看到过滤器和拦截器的不同作用范围、实现方式和使用场景。在选择使用哪个时,通常是根据需要在 Servlet 层还是 Spring MVC 层对请求进行处理来决定的。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/169432.html