杰瑞科技汇

Servlet开发入门关键步骤是什么?

目录

  1. Servlet 是什么?
  2. Servlet 开发环境准备
  3. 创建第一个 Servlet (手动配置)
    • 1 创建 Web 项目
    • 2 编写 Servlet 代码
    • 3 配置 web.xml (部署描述符)
    • 4 部署到 Tomcat 并运行
  4. 使用注解简化配置 (Servlet 3.0+)
  5. Servlet 生命周期详解
  6. 处理请求和响应
    • 1 获取请求信息 (HttpServletRequest)
    • 2 设置响应信息 (HttpServletResponse)
  7. 实战案例:用户登录
  8. 总结与最佳实践

Servlet 是什么?

Servlet (Server Applet) 是运行在 Web 服务器上的 Java 程序,它使用 Java 语言编写的、能够响应客户端(通常是浏览器)请求并生成动态内容的类。

Servlet开发入门关键步骤是什么?-图1
(图片来源网络,侵删)

你可以把它想象成一个“Web 上的 Java 程序员”,当你在浏览器中输入一个网址(http://localhost:8080/myapp/hello),Web 服务器(如 Tomcat)就会找到对应的 Servlet 程序来处理这个请求,然后把处理结果(通常是 HTML 页面)返回给你的浏览器。

核心作用:

  • 接收 HTTP 请求:来自客户端的 GET、POST 等请求。
  • 处理业务逻辑:比如查询数据库、计算数据、验证用户等。
  • 生成动态响应:将处理结果生成 HTML、JSON、XML 等格式,返回给客户端。

Servlet API 是 Java EE(现为 Jakarta EE)规范的一部分,位于 javax.servletjavax.servlet.http 包中。


Servlet 开发环境准备

在开始之前,你需要准备好以下工具:

Servlet开发入门关键步骤是什么?-图2
(图片来源网络,侵删)
  1. JDK (Java Development Kit): Java 开发工具包,建议使用 JDK 8 或更高版本。
  2. Web 服务器: 最常用的是 Apache Tomcat,它是 Servlet 和 JSP 规范的参考实现,你可以从 Tomcat 官网 下载并安装。
  3. IDE (集成开发环境): IntelliJ IDEA (社区版即可) 或 Eclipse 都非常合适,它们对 Java Web 开发有很好的支持。
  4. 构建工具 (可选但推荐): Maven 或 Gradle,用于管理项目依赖和构建过程。

创建第一个 Servlet (手动配置)

我们将以 IntelliJ IDEA 为例,创建一个最基础的 Servlet。

1 创建 Web 项目

  1. 打开 IntelliJ IDEA,选择 File -> New -> Project
  2. 在左侧选择 Java Enterprise
  3. 勾选 Web Application,并确保 Application server 选择你配置好的 Tomcat。
  4. 设置 Project name (my-first-servlet) 和 Project location。
  5. 点击 Create

IDEA 会自动为你创建一个标准的 Web 项目结构,其中最重要的是:

  • src: 存放你的 Java 源代码。
  • web: 存放 Web 资源,如 HTML、CSS、JS 文件。
  • web/WEB-INF: 这是一个特殊目录,里面的内容对客户端是不可见的。
    • web/WEB-INF/web.xml: 部署描述符,用于配置 Servlet、过滤器、监听器等,这是 Servlet 2.5 及以前版本的核心配置文件。

2 编写 Servlet 代码

  1. src 目录下,创建一个包,com.example.servlet
  2. 在该包下,创建一个 Java 类,命名为 HelloServlet
package com.example.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
// 1. 继承 HttpServlet 类
public class HelloServlet extends HttpServlet {
    // 2. 重写 doGet 或 doPost 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 3. 设置响应内容类型为 HTML
        resp.setContentType("text/html;charset=UTF-8");
        // 4. 获取输出流,向客户端写入响应内容
        resp.getWriter().println("<h1>Hello, Servlet World!</h1>");
        resp.getWriter().println("<p>当前时间是: " + new java.util.Date() + "</p>");
    }
}

代码解释:

  • extends HttpServlet: 我们编写的 Servlet 类必须继承 HttpServlet,它是专门用于处理 HTTP 请求的 Servlet 基类。
  • @Override protected void doGet(...): 当客户端发送 GET 请求时,Tomcat 会调用这个方法,同样,如果是 POST 请求,你需要重写 doPost 方法。
  • HttpServletRequest req: 代表客户端的请求对象,可以从中获取请求参数、请求头、会话等信息。
  • HttpServletResponse resp: 代表服务端的响应对象,用于向客户端返回数据。
  • resp.setContentType(...): 设置响应的 MIME 类型,这里我们告诉浏览器,我返回的是 HTML 文本,并且使用 UTF-8 编码,避免中文乱码。
  • resp.getWriter(): 获取一个字符输出流,通过 println() 方法向浏览器写入内容。

3 配置 web.xml

我们需要告诉 Tomcat,当用户访问哪个 URL 时,应该调用我们刚刚创建的 HelloServlet,这个配置就在 web.xml 文件中。

Servlet开发入门关键步骤是什么?-图3
(图片来源网络,侵删)

打开 web/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 的内部名称,可以自定义 -->
        <servlet-name>helloServlet</servlet-name>
        <!-- Servlet 的全限定类名 -->
        <servlet-class>com.example.servlet.HelloServlet</servlet-class>
    </servlet>
    <!-- Servlet 映射 -->
    <servlet-mapping>
        <!-- 将哪个映射指向上面定义的 Servlet -->
        <servlet-name>helloServlet</servlet-name>
        <!-- 访问的 URL 模式。/hello 表示上下文根路径为 /hello 的请求 -->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

配置解释:

  • <servlet>: 标签用来定义一个 Servlet。
    • <servlet-name>: 给 Servlet 起一个内部名称。
    • <servlet-class>: 指定这个 Servlet 对应的 Java 类的全名。
  • <servlet-mapping>: 标签用来将一个 URL 映射到一个已定义的 Servlet。
    • <servlet-name>: 这里引用的名称必须和上面 <servlet> 中定义的 <servlet-name> 一致。
    • <url-pattern>: 定义一个 URL 模式。/hello 意味着所有以 /hello 结尾的请求都会由这个 Servlet 处理。

4 部署到 Tomcat 并运行

  1. 点击 IntelliJ IDEA 右上角的 "Add Configuration" 或 "Edit Configurations"。
  2. 点击 号,选择 Tomcat Server -> Local
  3. Deployment 标签页,点击 号,选择 Artifact,然后选择你的 my-first-servlet:war exploded
  4. 设置 Application context(应用上下文),通常和项目名一致,/my-first-servlet
  5. 点击 OK 保存配置。
  6. 点击绿色的 "Run" 按钮(或按 Shift + F10)。

如果一切顺利,Tomcat 会启动,你的项目会被部署,打开你的浏览器,访问地址:

http://localhost:8080/my-first-servlet/hello

你应该能看到浏览器中显示:

Hello, Servlet World!

当前时间是: Mon Jan 01 10:00:00 CST 2025

恭喜!你的第一个 Servlet 成功运行了!


使用注解简化配置 (Servlet 3.0+)

从 Servlet 3.0 规范开始,引入了注解来简化开发,我们不再需要手动编写繁琐的 web.xml 配置。

  1. 修改 Servlet 类

HelloServlet 类上添加 @WebServlet 注解:

package com.example.servlet;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
// 使用注解进行配置
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println("<h1>Hello, Annotation-based Servlet!</h1>");
    }
}

注解解释:

  • @WebServlet: 这个注解替代了 <servlet><servlet-mapping> 的配置。
    • name: 对应 <servlet-name>
    • urlPatterns: 对应 <url-pattern>,可以是一个字符串数组,表示支持多个 URL 模式。
  1. 移除或保留 web.xml

你可以删除或清空 web.xml 文件,项目依然可以正常运行。web.xml 已经不是必需的了,但如果你需要配置一些更复杂的全局设置(如欢迎页面、错误页面、过滤器等),保留它仍然是一个好习惯。


Servlet 生命周期详解

理解 Servlet 的生命周期对于编写健壮的代码至关重要,一个 Servlet 实例的生命周期由容器(如 Tomcat)管理,主要包括以下三个阶段:

  1. 初始化

    • 何时发生:当客户端第一次请求该 Servlet 时,或者服务器启动时(在 web.xml 中配置 <load-on-startup>)。
    • 调用方法init(ServletConfig config) 方法。
    • 特点只执行一次,通常在这个方法中进行一些一次性的初始化操作,比如加载配置文件、建立数据库连接等。init 方法执行完毕后,Servlet 就处于“就绪”状态,可以处理请求了。
  2. 处理请求

    • 何时发生:在 Servlet 初始化后,每次客户端请求该 Servlet 时。
    • 调用方法service(ServletRequest req, ServletResponse res) 方法,对于 HttpServlet,它会根据请求的 method (GET, POST, PUT, DELETE...) 来调用相应的 doGet(), doPost() 等方法。
    • 特点:可以被调用多次,每次请求都会在独立的线程中执行,Servlet 本身是线程不安全的,要共享数据,必须注意同步问题。
  3. 销毁

    • 何时发生:当服务器关闭或应用被卸载时。
    • 调用方法destroy() 方法。
    • 特点只执行一次,通常在这个方法中进行资源释放操作,比如关闭数据库连接、文件流等。

示例代码:

@WebServlet("/lifecycle")
public class LifecycleServlet extends HttpServlet {
    // 1. 初始化阶段
    @Override
    public void init() throws ServletException {
        System.out.println("Servlet 初始化... (init() 方法被调用)");
    }
    // 2. 处理请求阶段
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("处理 GET 请求... (doGet() 方法被调用)");
        resp.getWriter().println("This is a lifecycle demo.");
    }
    // 3. 销毁阶段
    @Override
    public void destroy() {
        System.out.println("Servlet 销毁... (destroy() 方法被调用)");
    }
}

你可以在 Tomcat 的控制台观察这三个方法的调用顺序。


处理请求和响应

1 获取请求信息 (HttpServletRequest)

这个对象封装了所有的 HTTP 请求信息。

// 在 doGet 或 doPost 方法中
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 获取请求参数
    String username = req.getParameter("username"); // <input name="username">
    String password = req.getParameter("password");
    String[] hobbies = req.getParameterValues("hobby"); // <input name="hobby" value="">
    // 2. 获取请求头
    String userAgent = req.getHeader("User-Agent");
    // 3. 获取请求方法
    String method = req.getMethod(); // "GET" or "POST"
    // 4. 获取请求URI
    String requestURI = req.getRequestURI(); // /my-first-servlet/login
    // 5. 获取请求URL
    StringBuffer requestURL = req.getRequestURL(); // http://localhost:8080/my-first-servlet/login
    // ... 业务逻辑处理 ...
}

2 设置响应信息 (HttpServletResponse)

这个对象用于构建并返回 HTTP 响应。

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 设置响应状态码
    resp.setStatus(HttpServletResponse.SC_OK); // 200 OK
    // 2. 设置响应头
    resp.setHeader("Cache-Control", "no-cache");
    // 3. 设置响应内容类型和编码 (推荐使用此方法)
    resp.setContentType("application/json;charset=UTF-8");
    // 4. 获取输出流
    // PrintWriter: 用于输出字符文本
    PrintWriter out = resp.getWriter();
    out.println("{\"status\": \"success\", \"message\": \"登录成功!\"}");
    // ServletOutputStream: 用于输出二进制数据 (如下载文件)
    // ServletOutputStream outputStream = resp.getOutputStream();
}

实战案例:用户登录

这是一个非常经典的 Servlet 应用。

目标:创建一个登录页面,用户输入用户名和密码,提交后由 Servlet 验证,并返回登录成功或失败的信息。

步骤:

  1. 创建登录页面 login.html (放在 web 目录下)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">用户登录</title>
</head>
<body>
    <h2>用户登录</h2>
    <form action="login" method="post">
        用户名: <input type="text" name="username"><br>
        密码:   <input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>
  • action="login": 表单提交的地址,这个 login 会在 web.xml 或注解中映射到我们的 Servlet。
  1. 创建 LoginServlet.java
package com.example.servlet;
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;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    // 模拟一个用户数据库
    private static final String CORRECT_USERNAME = "admin";
    private static final String CORRECT_PASSWORD = "123456";
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 设置请求编码 (防止 POST 请求中文乱码)
        req.setCharacterEncoding("UTF-8");
        // 2. 设置响应编码
        resp.setContentType("text/html;charset=UTF-8");
        // 3. 获取表单数据
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 4. 业务逻辑验证
        if (CORRECT_USERNAME.equals(username) && CORRECT_PASSWORD.equals(password)) {
            // 登录成功
            resp.getWriter().println("<h1 style='color: green;'>登录成功!欢迎, " + username + "!</h1>");
        } else {
            // 登录失败
            resp.getWriter().println("<h1 style='color: red;'>登录失败!用户名或密码错误。</h1>");
            // 提供返回登录页面的链接
            resp.getWriter().println("<a href='login.html'>返回登录</a>");
        }
    }
}
  1. 运行测试
    • 启动 Tomcat。
    • 访问 http://localhost:8080/my-first-servlet/login.html
    • 输入正确的用户名 admin 和密码 123456,观察成功页面。
    • 输入错误的密码,观察失败页面。

总结与最佳实践

  • 职责分离:Servlet 的核心职责是接收请求、处理业务逻辑、返回响应,不要在 Servlet 中写大量的 HTML 代码,这会使代码难以维护,我们会使用 JSP (JavaServer Pages) 或现代的前端模板引擎来展示视图,Servlet 只负责准备数据并转发请求。
  • 中文乱码问题
    • GET 请求乱码:Tomcat 8+ 之后已经默认使用 UTF-8 编码,通常不会乱码,如果遇到,可以手动对 URL 参数进行解码:new String(username.getBytes("ISO-8859-1"), "UTF-8")
    • POST 请求乱码:务必在获取参数前调用 req.setCharacterEncoding("UTF-8");,或者使用一个全局的过滤器来统一处理。
  • 使用过滤器:对于通用的功能,如字符编码设置、登录验证、日志记录等,应该使用过滤器,过滤器可以对一组 Servlet 或 URL 模式进行预处理和后处理,实现代码复用。
  • 拥抱现代框架:虽然 Servlet 是 Java Web 开发的基础,但在实际企业级项目中,通常会使用更高级的框架,如 Spring MVCJakarta EE (Jakarta EE),这些框架在 Servlet 的基础上进行了封装,提供了更强大的功能(如依赖注入、RESTful 支持、AOP 等),极大地简化了开发,但理解 Servlet 是学习和使用这些高级框架的基石。

希望这份详细的指南能帮助你顺利入门 Java Servlet 开发!

分享:
扫描分享到社交APP
上一篇
下一篇