本文已完整覆盖 Servlet 所有核心知识点,适合 Java 后端初学者、面试备考、项目开发,全文干货无废话,建议收藏反复阅读!

 前言

Servlet 是 JavaWeb 开发的基石,是每一位 Java 后端开发者必须 100% 掌握的核心技术。无论是传统 JavaWeb 项目,还是 Spring Boot、Spring MVC 等主流框架,底层全部基于 Servlet 实现

本文将从概念、接口、生命周期、HttpServlet、配置映射、ServletConfig、ServletContext、高频面试题全方位讲解,带你彻底吃透 Servlet,轻松应对开发与面试。

 一、Servlet 核心概念

1.1 什么是 Servlet

Servlet = Server Applet,运行在 Web 服务器(如 Tomcat)中的小型 Java 程序。基于 HTTP 协议接收、处理、响应客户端请求,是前端与后端业务逻辑的核心桥梁。

一句话总结:用户的所有请求,最终都由 Servlet 处理!

登录 → 登录 Servlet

注册 → 注册 Servlet

查询 → 查询 Servlet

1.2 JavaWeb 三大组件

Servlet 是三大组件之首,必须掌握:

  1. Servlet:处理用户请求
  2. Filter(过滤器):请求拦截、编码、权限校验
  3. Listener(监听器):观察者模式,监听域对象生命周期

二、Servlet 接口与原生开发

2.1 Servlet 核心接口

所有 Servlet 必须实现 javax.servlet.Servlet 接口,共 5 个方法:

方法 作用 调用时机
init(ServletConfig) 初始化 实例创建后仅调用 1 次
service(req,res) 处理请求 每次请求必调用
destroy() 销毁 Tomcat 关闭时调用
getServletConfig() 获取配置 手动调用
getServletInfo() 描述信息 基本不用

2.2 手写第一个 Servlet(原生版)

① 编写 Servlet 实现类
package cn.tx.servlet;

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class Servlet1 implements Servlet {

    // 初始化:只执行一次
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("Servlet1 初始化...");
    }

    // 获取配置对象
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    // 核心:处理请求
    @Override
    public void service(ServletRequest req, ServletResponse res) 
            throws ServletException, IOException {
        System.out.println("Servlet1 处理请求...");
        
        // 响应中文
        res.setContentType("text/html;charset=UTF-8");
        PrintWriter out = res.getWriter();
        out.write("Hello Servlet!我是原生 Servlet");
    }

    // 描述信息
    @Override
    public String getServletInfo() {
        return null;
    }

    // 销毁:服务器关闭执行
    @Override
    public void destroy() {
        System.out.println("Servlet1 销毁...");
    }
}
② web.xml 配置访问路径
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- 注册 Servlet -->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>cn.tx.servlet.Servlet1</servlet-class>
    </servlet>

    <!-- 配置访问地址 -->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>

2.3 Tomcat 请求响应完整流程

  1. 浏览器访问:http://localhost:8080/项目名/hello
  2. Tomcat 解析 URL,匹配 web.xml<url-pattern>
  3. 根据名称找到对应 <servlet-class>
  4. 反射创建 Servlet 实例(仅第一次请求创建)
  5. 调用 service() 处理请求
  6. 响应结果返回浏览器

三、Servlet 生命周期(面试必考)

Servlet 生命周期完全由 Tomcat 管理,我们只写逻辑,不负责创建 / 调用。

3.1 完整生命周期四步走

  1. 实例化:默认第一次访问时,Tomcat 反射创建对象
  2. 初始化:调用 init()只执行 1 次
  3. 服务:每次请求调用 service()
  4. 销毁:Tomcat 关闭 → 调用 destroy() → 释放资源

核心结论:一个 Servlet 类,Tomcat 只创建一个实例 → 单例多线程

3.2 配置 Tomcat 启动时创建 Servlet

默认第一次访问创建,可通过 <load-on-startup> 提前创建:

<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>cn.tx.servlet.Servlet1</servlet-class>
    <!-- 数字越小优先级越高,≥0 启动即创建 -->
    <load-on-startup>1</load-on-startup>
</servlet>

四、HttpServlet 企业级开发(最常用)

原生 Servlet 必须实现所有方法,开发繁琐。实际开发 100% 使用 HttpServlet!

4.1 继承体系

Servlet(接口)→ GenericServlet(抽象类)→ HttpServlet(HTTP专用)

4.2 快速编写 HttpServlet

package cn.tx.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class Servlet2 extends HttpServlet {

    // 处理 GET 请求
    @Override
    protected void doGet(HttpServletRequest request, 
                         HttpServletResponse response) 
            throws ServletException, IOException {
        doPost(request, response);
    }

    // 处理 POST 请求
    @Override
    protected void doPost(HttpServletRequest request, 
                          HttpServletResponse response) 
            throws ServletException, IOException {
        
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.write("Hello HttpServlet!企业开发标准写法");
    }
}

4.3 HTTP 常见请求方法

  • GET:查询资源
  • POST:提交数据
  • PUT:修改资源
  • DELETE:删除资源
  • HEAD:只获取响应头

五、Servlet 路径映射规则

5.1 三种匹配方式

  1. 完全路径匹配:以 / 开头,精准匹配
    • 示例:/hello/user/login
  2. 目录匹配:以 / 开头 + /*
    • 示例:/user/*/*
  3. 扩展名匹配:不能以 / 开头
    • 示例:*.do*.action

5.2 匹配优先级(必背)

完全路径匹配 > 目录匹配 > 扩展名匹配

 禁止写法:/*.do → 语法错误,Tomcat 无法启动

5.3 经典匹配示例

请求 URL 匹配规则 执行 Servlet
/abc /abc 精准匹配
/abc/a.html /abc/* 目录匹配
/a.do *.do 扩展名匹配

六、ServletConfig 单个 Servlet 配置

6.1 作用

封装当前 Servlet 私有配置,一个 Servlet 对应一个 ServletConfig。

6.2 配置私有参数

<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>cn.tx.servlet.Servlet1</servlet-class>
    
    <!-- 单个 Servlet 初始化参数 -->
    <init-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </init-param>
    <init-param>
        <param-name>password</param-name>
        <param-value>txjava</param-value>
    </init-param>
</servlet>

6.3 获取参数

@Override
public void init(ServletConfig config) throws ServletException {
    // 获取单个参数
    String username = config.getInitParameter("username");
    System.out.println("username:" + username);

    // 获取所有参数名
    Enumeration<String> names = config.getInitParameterNames();
    while (names.hasMoreElements()) {
        String name = names.nextElement();
        String value = config.getInitParameter(name);
        System.out.println(name + " = " + value);
    }
}

七、ServletContext 全局域对象(重点)

7.1 核心特点

一个 Web 应用只有一个 ServletContext

服务器启动创建,服务器关闭销毁

所有 Servlet 共享数据,全局作用域

7.2 常用 API

方法 功能
getInitParameter(name) 获取全局参数
setAttribute(name,value) 存数据
getAttribute(name) 取数据
getRealPath(path) 获取服务器真实路径
getResourceAsStream(path) 获取文件流

7.3 配置全局参数(所有 Servlet 共享)

<!-- 全局参数 -->
<context-param>
    <param-name>company</param-name>
    <param-value>达内教育</param-value>
</context-param>

7.4 实战:统计网站总访问次数

@Override
protected void doPost(HttpServletRequest request, 
                      HttpServletResponse response) 
        throws ServletException, IOException {

    ServletContext context = getServletContext();
    
    // 取出次数
    Integer count = (Integer) context.getAttribute("visitCount");
    count = count == null ? 1 : count + 1;
    
    // 存入域对象
    context.setAttribute("visitCount", count);
    
    // 响应
    response.setContentType("text/html;charset=UTF-8");
    response.getWriter().write("总访问次数:" + count);
}

7.5 读取资源文件三种方式

// 方式1:获取真实路径
String path = context.getRealPath("/test.properties");

// 方式2:直接获取文件流
InputStream is1 = context.getResourceAsStream("/WEB-INF/test.properties");

// 方式3:类加载器(通用,不依赖 Servlet)
InputStream is2 = this.getClass().getClassLoader()
                         .getResourceAsStream("test.properties");

八、Servlet 高频面试题(背会稳拿分)

8.1 Servlet 是单例吗?为什么线程不安全?

是单例:Tomcat 对每个 Servlet 只创建一个实例

线程不安全:多线程并发访问同一个实例,成员变量会被共享覆盖

解决方案:不定义成员变量、使用局部变量、使用 ThreadLocal

8.2 Servlet 生命周期(必背 3 步)

  1. 创建:第一次请求 → 反射实例化
  2. 初始化:执行 init() → 仅一次
  3. 服务:每次请求 → service()
  4. 销毁:服务器关闭 → destroy()

8.3 ServletConfig vs ServletContext

对比项 ServletConfig ServletContext
作用域 当前 Servlet 整个 Web 应用
创建时机 Servlet 创建时 服务器启动时
共享范围 自己 所有 Servlet
用途 私有配置 全局数据、文件读取

九、全文总结

本文完整覆盖 Servlet 从入门到精通所有核心:

  1. Servlet 概念 + JavaWeb 三大组件
  2. 原生 Servlet 接口 + 生命周期
  3. HttpServlet 企业开发写法
  4. 路径映射优先级
  5. ServletConfig 私有配置
  6. ServletContext 全局共享 + 访问量统计实战
  7. 高频面试题
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐