Servlet接口
Servlet 接口详解:Java Web 开发的基石
Servlet 是 Java Web 技术的核心组件,负责处理客户端请求并生成动态响应。它由 Servlet 容器管理,遵循标准化的生命周期,是构建 Java Web 应用的基础。本文将从 Servlet 的核心概念、接口方法、生命周期、配置方式及相关对象等方面,全面解析 Servlet 技术。
Servlet 与 Servlet 容器
1. 什么是 Servlet?
Servlet 是运行在 Web 服务器中的 Java 类,用于处理客户端(如浏览器)的 HTTP 请求并生成动态内容。它具有以下特点:
- 平台无关:基于 Java 技术,可在任何支持 Java 的 Web 服务器上运行;
- 由容器管理:生命周期(创建、初始化、服务、销毁)完全由 Servlet 容器控制;
- 动态内容生成:通过接收请求参数、访问数据库等方式,生成个性化响应。
2. 什么是 Servlet 容器?
Servlet 容器是 Web 服务器(如 Tomcat、Jetty)的一部分,负责与 Servlet 交互并管理其生命周期。其核心功能包括:
- 加载和实例化 Servlet 类;
- 调用 Servlet 的生命周期方法(
init、service、destroy); - 处理 HTTP 请求与响应的封装(将底层 TCP 数据转换为
HttpServletRequest/HttpServletResponse对象); - 管理 Servlet 之间的共享资源(如
ServletContext)。
Servlet 接口核心方法
javax.servlet.Servlet 接口定义了 Servlet 与容器交互的标准协议,包含 5 个核心方法:
public interface Servlet {
// 初始化 Servlet,容器创建 Servlet 后调用,仅执行一次
void init(ServletConfig config) throws ServletException;
// 获取 Servlet 的配置信息(如初始化参数)
ServletConfig getServletConfig();
// 处理客户端请求,每次请求都会调用
void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
// 返回 Servlet 的元信息(如作者、版本)
String getServletInfo();
// 销毁 Servlet,释放资源,容器卸载时调用,仅执行一次
void destroy();
}
方法详解:
init(ServletConfig config)- 触发时机:Servlet 实例被创建后(首次请求时或容器启动时,取决于
load-on-startup配置); - 作用:初始化资源(如加载配置、连接数据库),
config参数包含 Servlet 的配置信息; - 注意:若重写此方法,需确保调用
super.init(config)(如在GenericServlet中),否则getServletConfig()会返回null。
- 触发时机:Servlet 实例被创建后(首次请求时或容器启动时,取决于
service(ServletRequest req, ServletResponse res)- 触发时机:每次客户端请求该 Servlet 时;
- 作用:接收请求(
ServletRequest)、处理业务逻辑、生成响应(ServletResponse); - 注意:
ServletRequest和ServletResponse是通用接口,HTTP 场景下会被转换为HttpServletRequest和HttpServletResponse。
destroy()- 触发时机:Servlet 容器关闭或应用卸载时;
- 作用:释放资源(如关闭数据库连接、停止后台线程)。
Servlet 的继承体系
为简化开发,Java 提供了 Servlet 接口的实现类,形成以下继承关系:

1. GenericServlet
实现 Servlet 和 ServletConfig 接口,提供默认实现:
- 封装
ServletConfig对象,可直接调用getInitParameter()等方法; - 提供无参
init()方法,避免重写init(ServletConfig)时忘记保存配置对象; - 未实现
service()方法(仍为抽象方法),需子类实现。
2. HttpServlet
继承 GenericServlet,专为 HTTP 协议设计,重写 service() 方法实现请求分发:
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 根据 HTTP 方法(GET/POST 等)分发到对应方法
String method = request.getMethod();
if (method.equals("GET")) {
doGet(request, response);
} else if (method.equals("POST")) {
doPost(request, response);
}
// 其他方法(PUT/DELETE 等)的处理...
}
开发中通常继承 HttpServlet,只需重写 doGet() 和 doPost() 即可处理 HTTP 请求:
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("Hello, GET!");
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("Hello, POST!");
}
}
Servlet 的注册与映射
Servlet 需在配置文件中注册并映射 URL 路径,才能被容器识别和访问。配置方式有两种:XML 配置和注解配置(Servlet 3.0+)。
XML 配置(web.xml)
<!-- 注册 Servlet -->
<servlet>
<servlet-name>MyServlet</servlet-name> <!-- 唯一标识 -->
<servlet-class>com.example.MyServlet</servlet-class> <!-- 全类名 -->
<!-- 初始化参数(仅当前 Servlet 可见) -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 加载时机:0 或正数表示容器启动时加载,值越小优先级越高;负数表示首次请求时加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 映射 URL 路径 -->
<servlet-mapping>
<servlet-name>MyServlet</servlet-name> <!-- 与注册时的名称一致 -->
<url-pattern>/myServlet</url-pattern> <!-- 访问路径,以 / 开头 -->
</servlet-mapping>
注解配置(Servlet 3.0+)
无需 web.xml,直接在 Servlet 类上添加 @WebServlet 注解:
public class MyServlet extends HttpServlet {
// ...
}
缺省 Servlet
容器(如 Tomcat)内置一个 “缺省 Servlet”,用于处理未被其他 Servlet 映射的请求(如静态资源:HTML、CSS 等)。其配置如下:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern> <!-- 匹配所有未被映射的请求 -->
</servlet-mapping>
Servlet 相关核心对象
ServletConfig
每个 Servlet 实例对应一个 ServletConfig 对象,用于获取当前 Servlet 的初始化参数和 ServletContext:
// 获取初始化参数
String encoding = getServletConfig().getInitParameter("encoding"); // 对应 <init-param>
Enumeration<String> paramNames = getServletConfig().getInitParameterNames();
// 获取 ServletContext
ServletContext context = getServletConfig().getServletContext();
ServletContext
代表整个 Web 应用,全局唯一,所有 Servlet 共享。主要功能:
- 获取全局初始化参数(
web.xml中<context-param>配置); - 访问 Web 应用资源(如获取文件路径、读取资源流);
- 共享数据(通过
setAttribute/getAttribute)。
示例:
<!-- 全局初始化参数(所有 Servlet 可见) -->
<context-param>
<param-name>appName</param-name>
<param-value>MyWebApp</param-value>
</context-param>
// 在 Servlet 中获取
ServletContext context = getServletContext();
String appName = context.getInitParameter("appName"); // "MyWebApp"
// 获取资源路径(服务器上的绝对路径)
String realPath = context.getRealPath("/WEB-INF/config.xml");
// 共享数据
context.setAttribute("userCount", 100);
int count = (int) context.getAttribute("userCount");
Servlet 生命周期
Servlet 的生命周期完全由容器管理,分为 4 个阶段:
1. 实例化(构造器)
- 触发时机:容器首次加载 Servlet 时(根据
load-on-startup配置); - 操作:容器调用 Servlet 的无参构造器创建实例(仅一次)。
2. 初始化(init())
- 触发时机:实例创建后立即调用;
- 操作:执行初始化逻辑(如加载配置、连接数据库),由
init(ServletConfig)实现,开发者可重写无参init()。
3. 服务(service())
- 触发时机:每次客户端请求该 Servlet 时;
- 操作:容器创建新线程调用
service()方法,处理请求并生成响应。对于 HTTP 请求,HttpServlet会分发到doGet()/doPost()等方法。
4. 销毁(destroy())
- 触发时机:容器关闭或应用卸载时;
- 操作:执行资源清理逻辑(如关闭连接、释放内存),仅调用一次。
生命周期流程图:
容器启动/首次请求 → 构造器(实例化) → init()(初始化) → 每次请求调用 service() → 容器关闭 → destroy()(销毁)