Servlet 快速入门

文章目录

    • 概念
    • [SpringBoot 测试案例](#SpringBoot 测试案例)
    • 执行原理
      • [传统 Servlet](#传统 Servlet)
      • [在 SpringBoot (嵌入式 Tomcat + Spring MVC) 中请求从浏览器到业务代码的完整步骤](#在 SpringBoot (嵌入式 Tomcat + Spring MVC) 中请求从浏览器到业务代码的完整步骤)
    • 参考

概念

运行在服务器端的小程序, Servlet 就是一个接口,定义 Java 类被浏览器访问到(Tomcat识别)的规则

SpringBoot 测试案例

创建简单的 SpringBoot 项目进行测试,首先创建 Java 空项目,根据 POM 配置文件构建简单的 SpringBoot 项目

xml 复制代码
    <dependencies>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>3.5.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.5.0</version>
        </dependency>
    </dependencies>

需要注意的是,如果是 Servlet5.0 以上需要 Jakarta EE 依赖,而 Servlet 4.0 及以下则需要 Java EE 依赖

Jakarta EE 依赖

xml 复制代码
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.0.0</version>
    <scope>provided</scope>
</dependency>

Java EE 依赖

xml 复制代码
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

创建 Servlet 测试类,抽象实现 Servlet 接口,添加 @WebServlet 注解并指定 URL 映射,使用 @WebServlet 注解声明了这个类为 Servlet,该注解会在部署时被容器处理,容器根据其具体的属性配置将相应的类部署为 Servlet。

@WebServlet 是 Servlet 3.0(Jakarta Servlet 3.0) 引入的注解,用来在 不写 web.xml 的情况下向 Servlet 容器注册一个 HttpServlet 子类。它与早期基于 web.xml 的 <servlet> / <servlet-mapping> 配置功能等价,但更符合 "约定优于配置" 的理念,能让一个普通 Java 类 就地声明 自己的元数据(名称、URL 映射、初始化参数等)并立刻生效。

java 复制代码
@WebServlet("/demo")
public class ServletDemo implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    // 提供服务的方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Hello Servlet!");
    }

    @Override
    public String getServletInfo() {
        return "";
    }

    @Override
    public void destroy() {

    }
}

在 SpringBoot 启动类中新增 @ServletComponentScan 注解,SpringBoot 会把所有带 @WebServlet@WebFilter@WebListener 的组件交给内置容器(Tomcat/Jetty/Undertow)自动注册。

java 复制代码
@SpringBootApplication
@ServletComponentScan
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

当访问 /demo 接口时,会输出 Hello Servlet!

shell 复制代码
2025-06-03T14:59:21.629+08:00  INFO 76957 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2025-06-03T14:59:21.633+08:00  INFO 76957 --- [           main] web.servlet.DemoApplication              : Started DemoApplication in 0.525 seconds (process running for 0.696)
Hello Servlet!

执行原理

传统 Servlet

  • 当服务器接收到客户端浏览器的请求后,会解析请求 URL 路径,获取访问 Servlet 的资源路径
  • 查找 web.xml 文件,是否找到对应的 <url-pattern> 标签体内容
  • 如果有,则在找到对应的 <servlet-class> 全类名
  • Tomcat 会将字节码文件加载到内容,并创建其对象
  • 调用其对应 service 方法

在 SpringBoot (嵌入式 Tomcat + Spring MVC) 中请求从浏览器到业务代码的完整步骤

  • 嵌入式 Tomcat 解析 HTTP 报文。RequestResponse 对象在 Tomcat 层创建后,仍按 Servlet 规范传递给下游组件
  • SpringBoot 没有 web.xml,在启动时自动向容器注册一个核心 Servlet ------ DispatcherServlet,并将所有路径(/)映射给它(DispatcherServletRegistrationBean 完成注册)
  • DispatcherServlet 统一接管,后续 URL 再由 Spring 框架内部解析,而不是 Tomcat 直接查找其他 Servlet
  • Spring 容器在启动阶段就把 DispatcherServlet 作为 Bean 创建并交给 Tomcat;若使用 @WebServletServletRegistrationBean 等方式,还能额外注册自定义原生 Servlet
  • Tomcat 把 HttpServletRequest/Response 交给 DispatcherServlet.service()
  • 之后进入 Spring MVC 专属流程
    • HandlerMapping:根据 URI、HTTP 方法匹配到具体 @Controller / @RestController 的方法(Handler)
    • HandlerAdapter:选用合适的适配器(通常是 RequestMappingHandlerAdapter)调用该方法
    • 调用业务方法:参数解析、依赖注入、校验、AOP 切面等在这一层生效;方法返回值随后被包装成 ModelAndView 或直接写回 JSON
    • ViewResolver / HttpMessageConverter:将返回值渲染成 HTML、JSON、XML 等;最后写入 HttpServletResponse
关键点
  • 自动装配,DispatcherServletAutoConfiguration 在 SpringBoot 启动时运行
    • 创建 DispatcherServlet Bean
    • 把其 URL 映射(默认为 /)注册到嵌入式 Tomcat(或 Jetty/Undertow)
    • 允许通过 spring.mvc.servlet.path 修改前缀,或定义多个 ServletRegistrationBean 手动注册其他 Servlet
  • 过滤器与监听器
    • 使用 FilterRegistrationBean@WebFilter@ServletComponentScan 或 Spring Security 的 FilterChain 定义过滤器
    • 容器仍按 Servlet 规范的 FilterServletListener 次序执行,只是对象由 Spring 托管并可享受依赖注入与配置属性。
流程图
text 复制代码
浏览器
  │
HTTP 请求
  │
嵌入式 Tomcat (解析协议、线程池)
  │
DispatcherServlet (统一入口)
  │
HandlerMapping → 找控制器
  │
HandlerAdapter → 解析参数 + AOP
  │
Controller 方法(业务逻辑)
  │
HttpMessageConverter / ViewResolver
  │
DispatcherServlet
  │
Tomcat 写回 HTTP 响应
  ▼
浏览器

参考

相关推荐
小莫分享1 小时前
github 镜像节点
java
链上Sniper1 小时前
智能合约状态快照技术:实现 EVM 状态的快速同步与回滚
java·大数据·linux·运维·web3·区块链·智能合约
缘来是庄2 小时前
设计模式之建造者模式
java·设计模式·建造者模式
小湘西2 小时前
Apache HttpClient 的请求模型和 I/O 类型
java·http·apache
沃夫上校2 小时前
Feign调Post接口异常:Incomplete output stream
java·后端·微服务
LeeGe2 小时前
SpringAOP中@within和@annotation以及 @within和@target的区别
后端
一个平平无奇的Java小学生2 小时前
Spring Cloud Alibaba 微服务从入门到生产部署完整指南
后端
一个平平无奇的Java小学生2 小时前
Spring Cloud Alibaba 微服务实战指南
后端
q567315232 小时前
Java Selenium反爬虫技术方案
java·爬虫·selenium
张小洛2 小时前
Spring IOC容器核心阶段解密:★Bean实例化全流程深度剖析★
java·后端·spring·ioc容器·bean实例化