本文已完整覆盖 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

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

九、全文总结

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

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

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐