【Servlet】从入门到理解:为了解决什么问题

目录

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。

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

八、总结

Servlet 解决的问题

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

一句话总结

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


参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值