拦截器和过滤器执行顺序
时间: 2025-05-20 20:35:50 浏览: 27
### Java中拦截器和过滤器的执行顺序及其区别
在Java Web开发中,**过滤器(Filter)** 和 **拦截器(Interceptor)** 是两个重要的概念,它们都用于拦截HTTP请求并对请求或响应进行预处理或后处理。然而,两者的运行机制、配置方式以及执行顺序存在显著差异。
#### 1. 过滤器与拦截器的主要区别
- **运行环境**
- 过滤器是由Servlet容器管理的标准组件,适用于任何基于Servlet的应用程序[^3]。
- 拦截器则由Spring框架提供支持,主要用于Spring MVC生态系统内的请求处理。
- **配置方式**
- 过滤器通常通过`web.xml`文件或使用`@WebFilter`注解来声明[^3]。
- 拦截器需要在Spring的配置类中显式注册,例如通过实现`WebMvcConfigurer`接口并调用`addInterceptors()`方法[^3]。
- **功能范围**
- 过滤器仅能操作`HttpServletRequest`和`HttpServletResponse`对象。
- 拦截器不仅可以操作这些标准对象,还可以访问Spring MVC特有的组件,如`Handler`实例和`ModelAndView`对象。
#### 2. 执行顺序分析
根据已有资料[^2],过滤器和拦截器的执行顺序遵循以下规律:
- 当一个HTTP请求到达服务器时,首先会经过过滤器链中的各个过滤器。
- 接着,在进入目标控制器之前,拦截器的`preHandle()`方法会被调用。
- 响应生成之后,拦截器的`postHandle()`方法会在视图渲染完成前被调用。
- 最终,在整个请求结束且响应发送回客户端之前,拦截器的`afterCompletion()`方法被执行,随后控制权交还给过滤器链以完成后续清理工作。
具体来说,典型的执行流程如下:
1. Filter Chain -> doFilter()
2. Interceptor -> preHandle()
3. Controller Logic Execution
4. Interceptor -> postHandle()
5. View Rendering (if applicable)
6. Interceptor -> afterCompletion()
7. Final Response Sent Back to Client via Filters[^2]
#### 3. 示例代码展示
##### (1)过滤器示例
```java
import javax.servlet.*;
import java.io.IOException;
@WebFilter(filterName = "myFilter", urlPatterns = {"/*"})
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 {
System.out.println("Before filtering...");
chain.doFilter(request, response);
System.out.println("After filtering...");
}
@Override
public void destroy() {}
}
```
##### (2)拦截器示例
```java
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Pre-handle method called");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Post-handle method called");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("After-completion method called");
}
}
```
##### (3)测试结果说明
假设我们有这样一个简单的API端点:
```java
@RestController
@RequestMapping("/example")
public class ExampleController {
@GetMapping("/hello")
public String sayHello() {
return "Hello from controller!";
}
}
```
当发出GET请求至`/example/hello`时,终端输出可能类似于这样:
```
Before filtering...
Pre-handle method called
[Controller logic executed here]
Post-handle method called
After-completion method called
After filtering...
```
这表明了各部分按照预期顺序依次触发。
---
###
阅读全文
相关推荐


















