本章学习目标

通过本章学习,你将掌握:

  • Servlet 的基本概念与作用
  • Servlet 接口体系结构
  • 手动编写、配置、运行第一个 Servlet 程序
  • web.xml 与注解两种配置方式
  • 请求处理与响应输出的基本写法

一、Servlet 是什么?

Servlet(Server Applet)是Java 编写的服务器端程序,运行在支持 Java 的 Web 服务器(如 Tomcat、Jetty)上,是 Java EE 规范的核心组件之一。

简单来说:Servlet 是客户端请求与服务器响应的中间层,负责接收浏览器(客户端)的 HTTP 请求,处理业务逻辑,最终返回 HTTP 响应给客户端。

它是 Java Web 开发的基础,所有主流 Java Web 框架(Spring MVC、Struts2)底层都是基于 Servlet 实现的。

二、Servlet 核心作用

  1. 接收客户端(浏览器)发送的 HTTP 请求(GET/POST/PUT 等)
  2. 处理请求(调用业务层、操作数据库、参数校验等)
  3. 生成 HTTP 响应(返回 HTML、JSON、文件、跳转页面等)
  4. 实现 Web 应用的动态资源处理(区别于静态 HTML/CSS/JS)

Servlet 核心接口与类

Servlet 技术体系有三个核心 API,是开发的基础:

1. Servlet 接口(顶层接口)

定义了 Servlet 必须实现的 5 个方法:

  • init(ServletConfig config):初始化
  • service(ServletRequest req, ServletResponse res):处理请求
  • destroy():销毁
  • getServletConfig():获取配置信息
  • getServletInfo():获取描述信息

2. GenericServlet 抽象类

  • 实现 Servlet 接口,做了默认实现
  • 简化开发,只需重写 service() 方法
  • 协议无关(不只是 HTTP)

3. HttpServlet 抽象类(开发最常用)

  • 继承 GenericServlet,专门处理 HTTP 协议
  • 封装了 HTTP 请求处理逻辑,自动分发 GET/POST 请求
  • 开发只需重写 doGet()doPost() 方法,无需处理底层协议

三、手动实现第一个 Servlet 程序

环境准备

  • JDK 8+
  • Tomcat 8.5+
  • IDEA/Eclipse

步骤 1:创建 Java Web 项目

创建普通 Java 项目,开启 Web 支持,配置 Tomcat 服务器。

步骤 2:编写 Servlet 类

继承 HttpServlet,重写 doGetdoPost 方法:

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

// 注解配置访问路径(Servlet 3.0 支持,无需 web.xml)
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {

    // 处理 GET 请求
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应编码与内容类型
        response.setContentType("text/html;charset=UTF-8");
        // 获取输出流
        PrintWriter out = response.getWriter();
        // 输出响应内容
        out.write("<h1>Hello Servlet!这是我的第一个 Servlet 程序</h1>");
        out.close();
    }

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

步骤 3:启动服务器访问

启动 Tomcat,浏览器访问:

plaintext

http://localhost:8080/项目名/HelloServlet

即可看到页面输出内容。

步骤 4:传统 web.xml 配置(兼容旧版本)

如果不使用注解,可在 WEB-INF/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_4_0.xsd"
         version="4.0">
    <!-- 配置 Servlet 类 -->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.example.HelloServlet</servlet-class>
    </servlet>
    <!-- 配置访问路径 -->
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/HelloServlet</url-pattern>
    </servlet-mapping>
</web-app>

四.Servlet 常用对象与功能

1. HttpServletRequest(请求对象)

  • 获取客户端请求信息
  • 常用方法:
    • request.getParameter("name"):获取请求参数
    • request.getRequestDispatcher():请求转发
    • request.setAttribute()/getAttribute():请求域存取值
    • request.getMethod():获取请求方式(GET/POST)

2. HttpServletResponse(响应对象)

  • 向客户端返回数据
  • 常用方法:
    • response.setContentType():设置响应类型
    • response.getWriter():获取字符输出流
    • response.sendRedirect():重定向
    • response.setStatus():设置响应状态码

3. ServletConfig(配置对象)

  • 获取当前 Servlet 的配置信息
  • 方法:getInitParameter() 获取初始化参数

4. ServletContext(应用上下文对象)

  • 代表整个 Web 应用,全局唯一
  • 作用:全局数据共享、读取资源文件、获取应用路径
  • 方法:setAttribute()/getAttribute()

五.请求转发 vs 重定向(面试高频)

1. 请求转发(forward)

java

运行

request.getRequestDispatcher("/success.jsp").forward(request, response);
  • 服务器内部跳转,浏览器地址栏不变
  • 一次请求,可共享 request 域数据
  • 只能跳转当前项目内资源
  • 效率更高

2. 重定向(redirect)

java

运行

response.sendRedirect("/index.jsp");
  • 浏览器重新发送请求,地址栏改变
  • 两次请求,不能共享 request 域数据
  • 可跳转到外部网站(如百度)
  • 效率较低

六.Servlet 线程安全问题

核心问题

Servlet 是单例多线程的:

  • 容器只创建一个 Servlet 实例
  • 多个请求同时访问时,会共用同一个实例

风险

如果在 Servlet 中定义成员变量,多线程并发修改会导致数据错乱。

解决方案

  1. 尽量不要在 Servlet 中定义成员变量
  2. 使用局部变量(线程安全)
  3. 必要时加锁(synchronized),但会降低性能
  4. 用 ThreadLocal 封装线程安全数据

七.Servlet 与框架的关系

Servlet 是底层基础,框架是对 Servlet 的封装简化:

  • Spring MVC:核心 DispatcherServlet 分发所有请求
  • Spring Boot:自动配置 Servlet 容器,无需手动编写 Servlet
  • 框架的作用:简化请求映射、参数封装、视图解析,提高开发效率

本质:框架 = Servlet + 封装 + 扩展 + 自动化配置

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐