Filter执行过程是什么?

3)Filter执行的顺序 
马 克-to-win:根据上面的说明“Filter的拦截的工作过程”的图,我们对Filter的Helloworld例子做一个小小的扩展(增加了一个 MarkToWinFilter2,代码和MarkToWinFilter几乎一样),来说明Filter的顺序,结论:filter-mapping在Web.xml中的顺序决定了Filter执行的顺序。
例 1.2.3
Web.xml中增加下一段:
     <filter>
        <filter-name>MarkToWinFilter2</filter-name>
        <filter-class>com.MarkToWinFilter2</filter-class>
    </filter>
    <filter>
        <filter-name>MarkToWinFilter</filter-name>
        <filter-class>com.MarkToWinFilter</filter-class>
    </filter>
  <filter-mapping>
      <filter-name>MarkToWinFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
    <filter-mapping>
      <filter-name>MarkToWinFilter2</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>



package com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
public class MarkToWinFilter2 implements Filter {
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        response.setCharacterEncoding("GBK");
        PrintWriter out = response.getWriter();
        out.println("之前 filterChain.doFilter2");
        System.out.println("之前 filterChain.doFilter2");
        chain.doFilter(request, response);
        System.out.println("之后 filterChain.doFilter2");
        out.println("之后 filterChain.doFilter2");
    }
    public void init(FilterConfig fConfig) throws ServletException {
    }
}

更多请看:https://blog.youkuaiyun.com/qq_44638460/article/details/104079515

<think>在Java Web开发中,特别是在Spring框架中,Filter和Interceptor都是用于处理HTTP请求的,但它们在作用范围、执行顺序和使用方式上有明显的区别。 ### Filter(过滤器) 1. **定义**:Filter是Servlet规范中定义的,属于Servlet容器的一部分,不依赖于Spring框架。 2. **作用位置**:Filter作用于请求进入Servlet容器之后,但在进入DispatcherServlet之前,以及在响应离开Servlet容器之前。 3. **实现方式**:通过实现`javax.servlet.Filter`接口,并在`web.xml`中配置或使用`@WebFilter`注解(Servlet 3.0+)进行注册。 4. **功能**:可以用于修改请求和响应的内容,例如字符编码转换、安全检查、日志记录等。 5. **执行顺序**:由`web.xml`中配置的顺序决定,或者通过`@Order`注解指定(但注意,`@WebFilter`默认顺序是不确定的,通常按照类名顺序,所以最好显式指定顺序)。 ### Interceptor(拦截器) 1. **定义**:Interceptor是Spring MVC框架中定义的,用于在请求处理的不同阶段进行拦截。 2. **作用位置**:Interceptor作用于请求进入DispatcherServlet之后,在Controller方法执行的前后以及视图渲染前后。具体来说: - `preHandle`:在Controller方法执行之前调用。 - `postHandle`:在Controller方法执行之后,视图渲染之前调用。 - `afterCompletion`:在请求完成之后,即视图渲染之后调用。 3. **实现方式**:通过实现`HandlerInterceptor`接口或继承`HandlerInterceptorAdapter`类,并在Spring MVC配置中注册。 4. **功能**:可以访问处理请求的Controller对象,因此可以用于权限检查、日志记录、性能监控等与业务逻辑相关的操作。 ### 执行顺序 当请求到达时,执行顺序如下: 1. **Filter**:首先执行Filter链(多个Filter按配置顺序执行)。 2. **DispatcherServlet**:请求被分发到对应的Controller。 3. **Interceptor**:在Controller方法执行前后,执行Interceptor的`preHandle`和`postHandle`方法;在请求完成时执行`afterCompletion`。 因此,**Filter先于Interceptor执行**。 ### 代码示例 #### Filter示例 ```java import javax.servlet.*; import java.io.IOException; public class ExampleFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 在请求处理之前(进入DispatcherServlet之前) System.out.println("Before Filter"); // 继续执行Filter链 chain.doFilter(request, response); // 在响应处理之后(离开Servlet容器之前) System.out.println("After Filter"); } @Override public void destroy() { // 销毁 } } ``` #### Interceptor示例 ```java import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ExampleInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 在Controller方法执行之前 System.out.println("preHandle"); return true; // 返回true则继续执行,false则中断 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { // 在Controller方法执行之后,视图渲染之前 System.out.println("postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 在请求完成之后,视图渲染之后 System.out.println("afterCompletion"); } } ``` ### 配置方式 #### Filter配置(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 FilterConfig { @Bean public FilterRegistrationBean<ExampleFilter> exampleFilter() { FilterRegistrationBean<ExampleFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new ExampleFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.setOrder(1); // 设置执行顺序 return registrationBean; } } ``` #### Interceptor配置 ```java 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 InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new ExampleInterceptor()) .addPathPatterns("/**") // 拦截所有路径 .order(1); // 设置拦截器顺序,数值越小越先执行 } } ``` ### 区别总结 | 特性 | Filter(过滤器) | Interceptor(拦截器) | |--------------|--------------------------------------|----------------------------------------| | 规范 | Servlet规范 | Spring MVC框架 | | 作用范围 | 作用于Servlet容器,范围更广 | 作用于Spring MVC的DispatcherServlet内 | | 依赖 | 不依赖Spring框架 | 依赖Spring MVC框架 | | 执行顺序 | 在Interceptor之前执行 | 在Filter之后执行 | | 可访问对象 | ServletRequest和ServletResponse | 可以访问Handler(Controller)对象 | | 异常处理 | 在Filter中处理异常 | 在Interceptor中处理异常(如afterCompletion) | | 配置方式 | web.xml或@WebFilter | Spring MVC配置 | ### 执行顺序图示 ``` HTTP Request | v Servlet Container | v Filter1 --> Filter2 --> ... --> FilterN | v DispatcherServlet | v Interceptor.preHandle | v Controller Method | v Interceptor.postHandle | v View Rendering | v Interceptor.afterCompletion | v Filter.doFilter (后半部分,即chain.doFilter之后) | v HTTP Response ``` ### 注意事项 1. **执行顺序**:多个Filter和Interceptor的执行顺序由它们的注册顺序决定(Filter通过`FilterRegistrationBean`的order,Interceptor通过`InterceptorRegistry`的order)。 2. **中断请求**: -Filter中,如果不调用`chain.doFilter`,则请求被中断。 - 在Interceptor的`preHandle`方法中,返回`false`则中断请求。 3. **异常处理**:如果在Filter或Interceptor中抛出异常,将不会继续执行后续的Filter或Interceptor。 §§相关问题§§: 1. 如何在Spring Boot中自定义Filter并指定执行顺序? 2. 拦截器(Interceptor)的postHandle和afterCompletion方法有什么区别? 3. 在Filter中如何修改HTTP请求的内容(例如请求体)? 4. 如何实现一个全局的异常处理机制,使得Filter和Interceptor中的异常能够被统一处理?</think>### Filter 与 Interceptor 的区别与执行顺序详解 #### 核心区别对比 | 特性 | Filter (过滤器) | Interceptor (拦截器) | |--------------|----------------------------------|-------------------------------------| | **规范/框架** | Servlet 规范 (Java EE 标准) | Spring 框架特有 | | **作用范围** | Web 容器级别 (Tomcat/Jetty等) | Spring MVC 上下文 | | **依赖** | 不依赖 Spring | 需要 Spring 环境 | | **拦截目标** | 所有 HTTP 请求/响应 | 仅 Spring MVC 处理的请求 | | **执行位置** | Servlet 前后 | Controller 方法前后 | | **访问对象** | ServletRequest/ServletResponse | HandlerMethod, ModelAndView | | **配置方式** | web.xml 或 @WebFilter | Spring 配置 (XML 或 JavaConfig) | #### 执行顺序详解 在请求处理流程中,Filter 和 Interceptor 的执行顺序如下: ```mermaid sequenceDiagram participant B as 浏览器 participant S as 服务器 participant F as Filter participant D as DispatcherServlet participant I as Interceptor participant C as Controller B->>S: HTTP 请求 S->>F: 进入 Filter 链 F->>F: 执行所有 Filter 的 doFilter() F->>D: 请求进入 DispatcherServlet D->>I: 调用 Interceptor.preHandle() I-->>D: 返回 true/false alt 返回 true D->>C: 执行 Controller 方法 C->>I: 完成后调用 Interceptor.postHandle() I->>D: 视图渲染前处理 D->>I: 调用 Interceptor.afterCompletion() else 返回 false D->>F: 直接返回响应 end D->>F: 响应返回 Filter 链 F->>F: 执行所有 Filter 的后置处理 F->>B: 返回最终响应 ``` **关键执行顺序**: 1. **Filter执行**:所有 Filter 按注册顺序执行前置处理 2. **Interceptor.preHandle**:在 Controller 方法执行前 3. **Controller 方法**:业务逻辑处理 4. **Interceptor.postHandle**:在 Controller 执行后,视图渲染前 5. **Interceptor.afterCompletion**:在视图渲染完成后 6. **Filter执行**:所有 Filter 按注册逆序执行后置处理 #### 详细区别解析 1. **作用范围不同**: - Filter 作用于整个 Web 容器,能拦截所有请求(包括静态资源) - Interceptor 只作用于 Spring MVC 处理的请求(Controller 方法) 2. **生命周期差异**: ```mermaid graph LR Filter[Filter 生命周期] --> Init[init] Filter --> DoFilter[doFilter] Filter --> Destroy[destroy] Interceptor[Interceptor 生命周期] --> PreHandle[preHandle] Interceptor --> PostHandle[postHandle] Interceptor --> AfterCompletion[afterCompletion] ``` 3. **异常处理能力**: - Filter 可以通过 `try-catch` 捕获处理链中的异常 - Interceptor 的 `afterCompletion` 方法可以处理 Controller 抛出的异常 4. **配置灵活性**: - Filter 支持 URL 模式匹配(/*, /api/*) - Interceptor 支持更精细的路径匹配和排除 ```java // Spring 拦截器配置示例 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/api/public/**"); } ``` 5. **性能影响**: - Filter 在更底层执行,性能开销更小 - Interceptor 可以访问 Spring 上下文,但需要更多资源 #### 典型使用场景 | 组件 | 适用场景 | |--------------|--------------------------------------------------------------------------| | **Filter** | 字符编码转换、全局日志记录、GZIP压缩、全站安全防护(XSS/CORS) | | **Interceptor** | 权限验证、业务日志、执行时间统计、Controller 级参数预处理/后处理 | #### 最佳实践建议 1. **选择原则**: - 需要处理静态资源 → 使用 Filter - 需要访问 Spring Bean → 使用 Interceptor - 需要处理文件上传等底层操作 → 使用 Filter 2. **执行顺序控制**: - Filter 顺序:通过 `@Order` 注解或 web.xml 配置顺序 - Interceptor 顺序:通过注册顺序控制(先注册先执行) 3. **组合使用示例**: ```mermaid graph TB Request --> Filter1[Filter: 日志记录] Filter1 --> Filter2[Filter: 字符编码] Filter2 --> Interceptor1[Interceptor: 权限验证] Interceptor1 --> Interceptor2[Interceptor: 参数校验] Interceptor2 --> Controller Controller --> Interceptor2 Interceptor2 --> Interceptor1 Interceptor1 --> Filter2 Filter2 --> Filter1 Filter1 --> Response ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mark_to_win

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值