目录

Servlet 是 Java 处理 HTTP 请求的规范,它封装了 HTTP 请求解析和响应构建,让开发者专注于业务逻辑。

一、先看看没有 Servlet 之前的问题

问题:Java 怎么处理 HTTP 请求?

问题清单

二、Servlet 是什么

一句话定义

拆解这个定义

Servlet 在哪里

三、Servlet 怎么解决问题

对比一下

Servlet 帮你做了什么

四、Servlet 和 Tomcat 的关系

请求流程

路径的作用

五、Servlet 核心概念

1. Servlet 接口

2. HttpServlet 抽象类

3. 生命周期

六、实际例子

1. 最简单的 Servlet

2. 获取请求参数

3. 处理表单提交

七、Servlet vs Controller

八、总结

Servlet 解决的问题

一句话总结


Servlet 是 Java 处理 HTTP 请求的规范,它封装了 HTTP 请求解析和响应构建,让开发者专注于业务逻辑。


一、先看看没有 Servlet 之前的问题

问题:Java 怎么处理 HTTP 请求?

在没有 Servlet 之前,Java 要处理 HTTP 请求,只能用原始的 Socket 编程:

// 原始 Socket 方式处理 HTTP 请求
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
    Socket client = serverSocket.accept();
    
    // 手动解析 HTTP 请求
    InputStream in = client.getInputStream();
    byte[] buffer = new byte[1024];
    int len = in.read(buffer);
    String request = new String(buffer, 0, len);
    
    // 手动解析请求行
    String[] lines = request.split("\n");
    String requestLine = lines[0];  // GET /hello HTTP/1.1
    String method = requestLine.split(" ")[0];  // GET
    String path = requestLine.split(" ")[1];    // /hello
    
    // 手动构建 HTTP 响应
    String response = "HTTP/1.1 200 OK\r\n" +
                      "Content-Type: text/html\r\n" +
                      "\r\n" +
                      "<h1>Hello World</h1>";
    
    OutputStream out = client.getOutputStream();
    out.write(response.getBytes());
    out.flush();
    client.close();
}

问题清单

问题 描述
代码繁琐 每次都要手动解析 HTTP 请求
重复代码 每个请求都要写同样的解析逻辑
难以维护 请求处理和业务逻辑混在一起
没有规范 每个人写法不一样,难以协作

二、Servlet 是什么

一句话定义

Servlet 是 Java 提供的用于处理 HTTP 请求的规范。

拆解这个定义

  • Servlet:Server Applet(服务器小程序)
  • 规范:定义了一套接口,让开发者实现
  • 处理 HTTP 请求:接收请求,返回响应

Servlet 在哪里

浏览器
   ↓
Tomcat(Web服务器)
   ↓
Servlet(处理请求)
   ↓
你的代码(业务逻辑)

三、Servlet 怎么解决问题

对比一下

没有 Servlet

// 手动解析 HTTP 请求
String[] lines = request.split("\n");
String method = lines[0].split(" ")[0];
String path = lines[0].split(" ")[1];

// 手动构建 HTTP 响应
String response = "HTTP/1.1 200 OK\r\n" +
                  "Content-Type: text/html\r\n" +
                  "\r\n" +
                  "<h1>Hello World</h1>";

有 Servlet

// 继承 HttpServlet,重写 doGet 方法
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        // 直接获取请求参数
        String name = req.getParameter("name");
        
        // 直接设置响应内容
        resp.setContentType("text/html");
        resp.getWriter().println("<h1>Hello " + name + "</h1>");
    }
}

Servlet 帮你做了什么

功能 没有 Servlet 有 Servlet
解析 HTTP 请求 手动解析字符串 自动封装成对象
构建 HTTP 响应 手动拼接字符串 通过对象设置
路由映射 手动判断路径 注解自动映射
生命周期 手动管理 Tomcat 自动管理

四、Servlet 和 Tomcat 的关系

请求流程

浏览器发送请求
    ↓
Tomcat(接收请求)
    ↓
根据路径找到对应的 Servlet
    ↓
Servlet 处理请求
    ↓
返回响应给浏览器

路径的作用

路径就是"门牌号",告诉 Tomcat 把请求交给哪个 Servlet。

@WebServlet("/user")
public class UserServlet extends HttpServlet {
    // ...
}

@WebServlet("/order")
public class OrderServlet extends HttpServlet {
    // ...
}

当有请求时

  • 访问 /user → Tomcat 把请求交给 UserServlet
  • 访问 /order → Tomcat 把请求交给 OrderServlet

五、Servlet 核心概念

1. Servlet 接口

Servlet 是一个接口,定义了 5 个方法:

public interface Servlet {
    void init(ServletConfig config);      // 初始化
    ServletConfig getServletConfig();     // 获取配置
    void service(ServletRequest req, ServletResponse resp);  // 处理请求
    String getServletInfo();              // 获取信息
    void destroy();                       // 销毁
}

2. HttpServlet 抽象类

实际开发中,我们继承 HttpServlet,它帮我们实现了 Servlet 接口:

public abstract class HttpServlet extends GenericServlet {
    
    // 处理 GET 请求
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 默认返回 405 Method Not Allowed
    }
    
    // 处理 POST 请求
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 默认返回 405 Method Not Allowed
    }
}

3. 生命周期

Servlet 的生命周期由 Tomcat 管理:

Tomcat 启动
    ↓
创建 Servlet 实例(只创建一次)
    ↓
调用 init() 方法(只调用一次)
    ↓
调用 service() 方法(每次请求都调用)
    ↓
根据请求方法调用 doGet() / doPost()
    ↓
Tomcat 关闭
    ↓
调用 destroy() 方法(只调用一次)

关键点

  • Servlet 实例是单例的(整个应用只有一个实例)
  • init()destroy() 只调用一次
  • service() 每次请求都会调用

六、实际例子

1. 最简单的 Servlet

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.getWriter().println("<h1>Hello World</h1>");
    }
}

访问http://localhost:8080/your-app/hello

2. 获取请求参数

@WebServlet("/user")
public class UserServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        // 获取查询参数
        String name = req.getParameter("name");
        String age = req.getParameter("age");
        
        resp.setContentType("text/html");
        resp.getWriter().println("<h1>用户信息</h1>");
        resp.getWriter().println("<p>姓名:" + name + "</p>");
        resp.getWriter().println("<p>年龄:" + age + "</p>");
    }
}

访问http://localhost:8080/your-app/user?name=张三&age=25

3. 处理表单提交

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        // 获取表单数据
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        
        // 验证用户名密码
        if ("admin".equals(username) && "123456".equals(password)) {
            resp.setContentType("text/html");
            resp.getWriter().println("<h1>登录成功</h1>");
        } else {
            resp.setContentType("text/html");
            resp.getWriter().println("<h1>登录失败</h1>");
        }
    }
}

七、Servlet vs Controller

Controller 是 Spring MVC 对 Servlet 的封装,实际开发用 Controller,不用手动写 Servlet。

对比项 Servlet Controller
技术 Java Web 原生技术 Spring MVC 封装
获取参数 req.getParameter() @RequestParam@RequestBody
返回响应 resp.getWriter() @ResponseBody
路由映射 @WebServlet @RequestMapping
使用场景 底层技术 实际开发推荐

八、总结

Servlet 解决的问题

问题 没有 Servlet 有 Servlet
解析 HTTP 请求 手动解析字符串 自动封装成对象
构建 HTTP 响应 手动拼接字符串 通过对象设置
路由映射 手动判断路径 注解自动映射
生命周期 手动管理 Tomcat 自动管理

一句话总结

Servlet 是 Java 处理 HTTP 请求的规范,它封装了 HTTP 请求解析和响应构建,让开发者专注于业务逻辑。


参考资料

Logo

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

更多推荐