从 Servlet 到 WebMvcConfigurer:Java Web 与 Spring Boot 的进阶之旅


从 Servlet 到 WebMvcConfigurer:Java Web 与 Spring Boot 的进阶之旅

最近,我在翻看一些 Spring Boot 项目代码时,注意到某些类实现了 WebMvcConfigurer 接口。这让我突然意识到,自己对 Java Web 基础------尤其是 Servlet ------的了解其实非常浅薄。Servlet 中似乎有 Filter 和 Interceptor 两个概念,我一直觉得它们肯定有区别,但具体是什么区别呢?而 WebMvcConfigurer 又是什么?它隶属于哪个体系,和 Servlet 又有什么联系?带着这些疑问,我决定深入研究一番。

这次探索的契机是我在解决跨域问题时,发现可以通过 @CrossOrigin 注解或者定义一个实现了 WebMvcConfigurer 的类来处理。于是,我对 Servlet 相关的细节产生了浓厚的兴趣。接下来,我将详细介绍 Servlet、Filter、Interceptor 和 WebMvcConfigurer 的概念、区别以及它们在 Spring Boot 中的应用场景。

一、Servlet:Java Web 的基石

Servlet 是 Java Web 开发的核心组件,全称是 Server Applet ,它运行在服务器端,用于处理客户端的请求并生成响应。一个典型的 Servlet 生命周期包括初始化(init)、处理请求(service 或具体的 doGetdoPost 等方法)以及销毁(destroy)。

在传统的 Java Web 开发中,Servlet 需要在 web.xml 中配置,例如:

xml 复制代码
<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.example.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/myServlet</url-pattern>
</servlet-mapping>

但在 Spring Boot 中,Servlet 的使用被高度抽象化,我们很少直接编写 Servlet,而是通过 Spring MVC 的 @Controller@RestController 来处理请求。Spring MVC 的核心是一个特殊的 Servlet ------ DispatcherServlet,它负责接收所有请求并分发给对应的控制器。

二、Filter:请求与响应的过滤器

Filter(过滤器)是 Servlet 规范的一部分,作用是在请求到达 Servlet 之前或响应返回客户端之前进行拦截和处理。Filter 的典型应用场景包括日志记录、权限验证、字符编码设置等。

Filter 的核心接口是 javax.servlet.Filter,需要实现三个方法:

  • init:初始化过滤器。
  • doFilter:执行过滤逻辑,可以通过 chain.doFilter(request, response) 将请求传递给下一个过滤器或目标 Servlet。
  • destroy:销毁过滤器。

一个简单的 Filter 示例:

java 复制代码
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter 初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        System.out.println("请求进入 Filter");
        chain.doFilter(request, response); // 放行请求
        System.out.println("响应离开 Filter");
    }

    @Override
    public void destroy() {
        System.out.println("Filter 销毁");
    }
}

web.xml 中配置:

xml 复制代码
<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在 Spring Boot 中,可以通过 @Component@Bean 将 Filter 注册到容器中,无需 web.xml

三、Interceptor:Spring MVC 的拦截器

Interceptor(拦截器)是 Spring MVC 的概念,不属于 Servlet 规范,而是 Spring 框架提供的更高级的请求拦截机制。Interceptor 作用于 DispatcherServlet 分发请求之后、控制器方法执行之前,主要用于更细粒度的逻辑处理,比如认证、日志、性能监控等。

Interceptor 的核心接口是 org.springframework.web.servlet.HandlerInterceptor,需要实现三个方法:

  • preHandle:在控制器方法执行前调用,返回 true 放行,false 拦截。
  • postHandle:在控制器方法执行后、视图渲染前调用。
  • afterCompletion:在视图渲染完成后调用,常用于清理资源。

一个简单的 Interceptor 示例:

java 复制代码
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("进入 Interceptor - preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("Interceptor - postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("Interceptor - afterCompletion");
    }
}

四、Filter 与 Interceptor 的区别

虽然 Filter 和 Interceptor 都能拦截请求,但它们的定位和功能有明显差异:

  1. 所属体系

    • Filter 属于 Servlet 规范,由 Servlet 容器管理。
    • Interceptor 属于 Spring MVC,由 Spring 容器管理。
  2. 拦截范围

    • Filter 作用于所有进入 Servlet 容器的请求(包括静态资源、Servlet 请求等)。
    • Interceptor 只作用于 Spring MVC 处理的请求,不会拦截静态资源(如 CSS、JS)。
  3. 执行时机

    • Filter 在 DispatcherServlet 之前执行。
    • Interceptor 在 DispatcherServlet 分发请求后、控制器方法执行前后执行。
  4. 功能深度

    • Filter 更粗粒度,主要处理请求和响应的通用逻辑。
    • Interceptor 更细粒度,可以访问 Spring 的上下文,操作 ModelAndView 等。
  5. 配置方式

    • Filter 通过 web.xml@Bean 配置。
    • Interceptor 通过实现 WebMvcConfigurer 添加。

执行顺序示意图:

css 复制代码
客户端请求 → Filter → DispatcherServlet → Interceptor → Controller → Interceptor → Filter → 客户端响应

五、WebMvcConfigurer:Spring MVC 的配置利器

WebMvcConfigurer 是 Spring MVC 提供的一个接口,用于自定义 Spring MVC 的配置。它隶属于 Spring Framework 的 org.springframework.web.servlet.config 包,主要用于扩展 DispatcherServlet 的功能,而不覆盖默认配置。

常见的配置方法包括:

  • addInterceptors:添加自定义拦截器。
  • addCorsMappings:配置跨域支持。
  • addViewControllers:添加视图控制器。
  • configureMessageConverters:自定义消息转换器。

一个解决跨域问题的示例:

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 匹配所有路径
                .allowedOrigins("http://localhost:8080") // 允许的源
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的方法
                .allowCredentials(true); // 允许携带凭证
    }
}

相比 @CrossOrigin 注解,WebMvcConfigurer 的优势在于可以全局配置跨域规则,而 @CrossOrigin 通常作用于单个控制器或方法。

WebMvcConfigurer 的上层架构

WebMvcConfigurer 是 Spring MVC 配置体系的一部分,其上层是 WebMvcConfigurationSupport 类。如果直接继承 WebMvcConfigurationSupport,会覆盖 Spring Boot 的默认 MVC 配置,因此推荐使用 WebMvcConfigurer 接口。

等价的替代方案:

  • Spring Boot 自动配置 :Spring Boot 通过 application.propertiesapplication.yml 提供了一些简化的配置,例如静态资源路径、跨域等。
  • 直接操作 DispatcherServlet:极少使用,过于底层。

六、跨域问题与 Servlet 的联系

跨域问题(CORS)是现代 Web 开发中的常见需求。在 Servlet 层面,可以通过 Filter 手动设置响应头来解决:

java 复制代码
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setHeader("Access-Control-Allow-Origin", "*");
        resp.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        resp.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(request, response);
    }
}

但在 Spring Boot 中,使用 WebMvcConfigurer@CrossOrigin 更符合框架的约定,代码更优雅,管理更集中。

七、总结与反思

通过这次学习,我终于弄清楚了 Servlet、Filter、Interceptor 和 WebMvcConfigurer 的关系:

  • Servlet 是 Java Web 的核心,Spring MVC 的 DispatcherServlet 是其现代演绎。
  • Filter 是 Servlet 规范的通用拦截机制,适用于全局请求处理。
  • Interceptor 是 Spring MVC 的专属拦截器,专注于控制器层逻辑。
  • WebMvcConfigurer 是 Spring MVC 的配置接口,提供了灵活的扩展点,比如跨域配置。
相关推荐
uhakadotcom4 分钟前
Tableau入门:数据可视化的强大工具
后端·面试·github
demonlg011222 分钟前
Go 语言 fmt 模块的完整方法详解及示例
开发语言·后端·golang
程序员鱼皮30 分钟前
2025 年最全Java面试题 ,热门高频200 题+答案汇总!
java·后端·面试
测试盐33 分钟前
django入门教程之cookie和session【六】
后端·python·django
天草二十六_简村人1 小时前
Rabbitmq消息被消费时抛异常,进入Unacked 状态,进而导致消费者不断尝试消费(下)
java·spring boot·分布式·后端·rabbitmq
uhakadotcom1 小时前
APM系统简介及案例
后端·面试·github
易元1 小时前
设计模式-外观模式
后端
低头不见1 小时前
Spring Boot 的启动流程
java·spring boot·后端
uhakadotcom2 小时前
Syslog投递日志到SIEM:基础知识与实践
后端·面试·github
uhakadotcom2 小时前
Flume 和 Logstash:日志收集工具的对比
后端·面试·github