杰瑞科技汇

Java Servlet 接口的核心作用是什么?

Servlet(Server Applet)是 Java EE 规范的一部分,它是一种用于开发动态 Web 资源的技术,Servlet 就是一个运行在 Web 服务器端的 Java 小程序,它接收来自客户端(通常是浏览器)的请求,并返回响应。

Java Servlet 接口的核心作用是什么?-图1
(图片来源网络,侵删)

核心概念:Servlet 接口

javax.servlet.Servlet 接口是所有 Servlet 必须实现的顶级接口,它定义了 Servlet 与 Servlet 容器(如 Tomcat、Jetty)之间进行生命周期交互的契约。

一个典型的 Servlet 开发流程是:

  1. 创建一个 Java 类
  2. 让这个类实现 Servlet 接口,并实现其所有方法。
  3. web.xml 文件中配置该 Servlet,将一个 URL 路径映射到这个 Java 类。
  4. 将应用打包成 WAR 文件,部署到 Servlet 容器中。

Servlet 接口的生命周期方法

Servlet 接口定义了三个核心的生命周期方法,以及两个其他方法,Servlet 容器(如 Tomcat)负责调用这些方法。

init(ServletConfig config)

  • 调用时机:当 Servlet 容器首次加载该 Servlet 实例时,会调用此方法。一个 Servlet 在其生命周期中只会被初始化一次
  • 作用:完成一次性的初始化操作,加载配置文件、建立数据库连接、创建缓存等。
  • 参数ServletConfig 对象,包含了 Servlet 的配置信息(如初始化参数)。
  • 示例
    @Override
    public void init(ServletConfig config) throws ServletException {
        // 获取初始化参数
        String driver = config.getInitParameter("dbDriver");
        System.out.println("Servlet 正在初始化,数据库驱动: " + driver);
        // ... 其他初始化代码 ...
    }

service(ServletRequest request, ServletResponse response)

  • 调用时机:每当客户端(浏览器)向该 Servlet 发送请求时,容器就会调用此方法。每次请求都会调用一次
  • 作用:这是 Servlet 的核心方法,用于处理客户端请求并生成响应,它会根据请求的类型(GET, POST, PUT, DELETE 等)来调用相应的 doGet(), doPost() 等方法。
  • 注意:通常我们不会直接重写 service() 方法,而是重写 doGet(), doPost() 等。GenericServlet(一个抽象类)已经为我们实现了 service() 方法,它会根据请求的 HTTP 方法来分发到具体的 doXxx() 方法。
  • 示例
    // 在 GenericServlet 或 HttpServlet 中,我们通常不直接重写这个
    // 而是重写 doGet 或 doPost

destroy()

  • 调用时机:当 Servlet 容器决定卸载该 Servlet 实例时(服务器关闭或应用被移除),会调用此方法。一个 Servlet 在其生命周期中也只会被销毁一次
  • 作用:进行资源清理,关闭数据库连接、释放文件句柄等。
  • 示例
    @Override
    public void destroy() {
        System.out.println("Servlet 正在销毁,正在关闭数据库连接...");
        // ... 清理资源的代码 ...
    }

Servlet 接口的其它方法

ServletConfig getServletConfig()

  • 作用:返回 ServletConfig 对象,该对象在 init() 方法中被传入,通过这个对象,可以获取 Servlet 的初始化参数、Servlet 上下文等。
  • 示例
    @Override
    public ServletConfig getServletConfig() {
        return this.servletConfig;
    }

String getServletInfo()

  • 作用:返回一个包含 Servlet 信息的字符串,如作者、版本、版权等,这只是一个辅助信息,容器可能会用它来管理 Servlet。
  • 示例
    @Override
    public String getServletInfo() {
        return "My First Servlet, Version 1.0";
    }

实际开发:使用 HttpServlet

直接实现 Servlet 接口非常繁琐,因为需要处理很多底层细节,在实际开发中,我们几乎总是继承 javax.servlet.http.HttpServlet 抽象类。

Java Servlet 接口的核心作用是什么?-图2
(图片来源网络,侵删)

HttpServlet 已经帮我们实现了:

  • Servlet 接口的所有方法。
  • service() 方法,它会根据 HTTP 请求方法(GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE)来调用对应的 doGet(), doPost() 等方法。

我们只需要:

  1. 创建一个类,继承 HttpServlet
  2. 重写 doGet()doPost() 等方法,来处理具体的业务逻辑。
  3. 配置 web.xml 或使用注解

示例代码

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;
// 使用注解进行配置,替代 web.xml
// @WebServlet("/hello") // 将此 Servlet 映射到 /hello 路径
public class HelloServlet extends HttpServlet {
    // 初始化方法(可选)
    @Override
    public void init() throws ServletException {
        System.out.println("HelloServlet 初始化...");
    }
    // 处理 GET 请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 设置响应内容类型和字符编码
        resp.setContentType("text/html;charset=UTF-8");
        // 2. 获取输出流,用于向客户端写入响应内容
        PrintWriter out = resp.getWriter();
        // 3. 生成 HTML 响应
        out.println("<html>");
        out.println("<head><title>Hello Servlet</title></head>");
        out.println("<body>");
        out.println("<h1>你好,世界!</h1>");
        out.println("<p>这是我的第一个 Servlet 程序。</p>");
        out.println("</body>");
        out.println("</html>");
    }
    // 处理 POST 请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // GET 和 POST 的处理逻辑可能不同
        // POST 用于提交表单数据
        String username = req.getParameter("username");
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><body>");
        out.println("<h1>POST 请求成功!</h1>");
        out.println("欢迎你, " + (username != null ? username : "访客"));
        out.println("</body></html>");
    }
    // 销毁方法(可选)
    @Override
    public void destroy() {
        System.out.println("HelloServlet 销毁...");
    }
}

配置方式

有两种主要的配置方式:

传统方式:web.xml (在 src/main/webapp/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.HelloServlet</servlet-class>
        <!-- 初始化参数(可选) -->
        <init-param>
            <param-name>dbDriver</param-name>
            <param-value>com.mysql.jdbc.Driver</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <!-- 将哪个 Servlet 映射到哪个 URL -->
        <servlet-name>HelloServlet</servlet-name>
        <!-- URL 模式,/hello 表示访问路径 -->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

现代方式:使用注解 @WebServlet (推荐)

从 Servlet 3.0 开始,支持使用注解来简化配置,如上面示例代码中的 @WebServlet("/hello")

Java Servlet 接口的核心作用是什么?-图3
(图片来源网络,侵删)
  • 优点:配置简单,代码和配置在一起,无需维护 web.xml
  • @WebServlet 常用属性
    • valueurlPatterns:指定 URL 模式。@WebServlet(value = "/hello")@WebServlet(urlPatterns = {"/hello", "/hi"})

HttpServletRequestHttpServletResponse

doGetdoPost 方法中,我们最常操作的就是这两个对象:

  • HttpServletRequest:代表客户端的请求对象,它封装了所有的请求信息。

    • req.getMethod(): 获取 HTTP 方法 (GET, POST)。
    • req.getRequestURI(): 获取请求的 URI。
    • req.getParameter("name"): 获取请求参数的值(用于表单提交)。
    • req.getHeader("User-Agent"): 获取请求头信息。
    • req.getSession(): 获取或创建 HttpSession 对象,用于会话管理。
  • HttpServletResponse:代表服务器的响应对象,我们通过它来向客户端返回数据。

    • resp.setContentType("text/html;charset=UTF-8"): 设置响应内容的类型和字符编码,防止中文乱码。
    • resp.setStatus(200): 设置 HTTP 状态码(200 表示成功,404 表示未找到等)。
    • resp.setHeader("Cache-Control", "no-cache"): 设置响应头。
    • resp.getWriter(): 获取字符输出流,用于输出文本内容。
    • resp.getOutputStream(): 获取字节输出流,用于输出图片、文件等二进制内容。

概念 描述
Servlet 接口 所有 Servlet 的顶层接口,定义了生命周期契约。
生命周期 init() -> service() (多次) -> destroy()
HttpServlet 实际开发中使用的基类,简化了 HTTP 请求处理。
doGet/doPost 我们最常重写的方法,用于处理具体的业务逻辑。
HttpServletRequest 封装了客户端的请求信息。
HttpServletResponse 封装了服务器的响应信息。
配置 传统 web.xml 和现代注解 @WebServlet 两种方式。

理解 Servlet 接口及其生命周期是掌握 Java Web 开发的基础,虽然现在有很多更高级的框架(如 Spring MVC),但它们在底层依然是基于 Servlet 原理工作的,学好 Servlet 对于理解整个 Java Web 生态系统至关重要。

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