全网最细 Servlet 教程:从入门到精通,JavaWeb 必学核心技术
本文已完整覆盖 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 是三大组件之首,必须掌握:
- Servlet:处理用户请求
- Filter(过滤器):请求拦截、编码、权限校验
- 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 请求响应完整流程
- 浏览器访问:
http://localhost:8080/项目名/hello - Tomcat 解析 URL,匹配
web.xml的<url-pattern> - 根据名称找到对应
<servlet-class> - 反射创建 Servlet 实例(仅第一次请求创建)
- 调用
service()处理请求 - 响应结果返回浏览器
三、Servlet 生命周期(面试必考)
Servlet 生命周期完全由 Tomcat 管理,我们只写逻辑,不负责创建 / 调用。
3.1 完整生命周期四步走
- 实例化:默认第一次访问时,Tomcat 反射创建对象
- 初始化:调用
init(),只执行 1 次 - 服务:每次请求调用
service() - 销毁: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 三种匹配方式
- 完全路径匹配:以
/开头,精准匹配- 示例:
/hello、/user/login
- 示例:
- 目录匹配:以
/开头 +/*- 示例:
/user/*、/*
- 示例:
- 扩展名匹配:不能以
/开头- 示例:
*.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 步)
- 创建:第一次请求 → 反射实例化
- 初始化:执行
init()→ 仅一次 - 服务:每次请求 →
service() - 销毁:服务器关闭 →
destroy()
8.3 ServletConfig vs ServletContext
| 对比项 | ServletConfig | ServletContext |
|---|---|---|
| 作用域 | 当前 Servlet | 整个 Web 应用 |
| 创建时机 | Servlet 创建时 | 服务器启动时 |
| 共享范围 | 自己 | 所有 Servlet |
| 用途 | 私有配置 | 全局数据、文件读取 |
九、全文总结
本文完整覆盖 Servlet 从入门到精通所有核心:
- Servlet 概念 + JavaWeb 三大组件
- 原生 Servlet 接口 + 生命周期
- HttpServlet 企业开发写法
- 路径映射优先级
- ServletConfig 私有配置
- ServletContext 全局共享 + 访问量统计实战
- 高频面试题
更多推荐




所有评论(0)