• HttpServlet详解


    Servlet与HttpServlet详解

    一、Servlet概述

    Servlet(Server Applet)是Java Servlet API中定义的一个接口,用于扩展Web服务器的功能。Servlet是一个运行在Web服务器或应用服务器上的Java程序,它可以动态地生成Web页面或其他类型的响应。

    二、HttpServlet类

    HttpServlet类是Java Servlet API中的一个核心类,它继承自GenericServlet类,实现了Servlet接口,并为HTTP协议提供了特定的实现。HttpServlet类的主要职责是处理HTTP请求和构建HTTP响应。

    HttpServlet的主要方法

    1. service(ServletRequest req, ServletResponse res)
      这是Servlet接口中的核心方法,所有来自客户端的请求首先都会调用此方法。HttpServlet为这个方法提供了默认实现,它会根据请求的类型(GET、POST等)调用对应的doXXX方法。

    2. doGet(HttpServletRequest request, HttpServletResponse response)
      用于处理HTTP GET请求。

    3. doPost(HttpServletRequest request, HttpServletResponse response)
      用于处理HTTP POST请求。

    4. doPut, doDelete, doOptions, doHead, doTrace
      这些方法用于处理其他类型的HTTP请求,但在常见的Web应用中很少直接使用。

    5. init(ServletConfig config)
      Servlet的初始化方法,当Servlet实例被加载到内存并准备使用时,容器会调用此方法。

    6. destroy()
      Servlet的销毁方法,当Servlet实例不再需要并被容器卸载时,容器会调用此方法。

    HttpServlet处理流程

    1. 部署Servlet

      • 开发者编写Servlet类,继承自HttpServlet并覆盖相应的方法。
      • 在Web应用的web.xml文件中配置Servlet的映射路径和初始化参数等信息。
      • 将Web应用打包成WAR文件并部署到Servlet容器中(如Tomcat)。
    2. 客户端请求

      • 客户端(如Web浏览器)发送HTTP请求到Servlet容器。
      • 请求中包含URL、HTTP方法(GET、POST等)、请求头、请求体等信息。
    3. 容器调度

      • Servlet容器接收到请求后,解析URL路径,找到与之匹配的Servlet实例。
      • 如果Servlet实例不存在,容器会创建一个。
    4. 调用service方法

      • Servlet容器调用Servlet实例的service方法,并传入HttpServletRequestHttpServletResponse对象。
      • HttpServletRequest对象包含了请求的所有信息,如参数、头信息等。
      • HttpServletResponse对象用于构建并发送HTTP响应。
    5. 处理请求

      • 根据请求的类型(如GET、POST),service方法会调用相应的doXXX方法。
      • 开发者在doXXX方法中实现业务逻辑,如访问数据库、处理数据等。
    6. 构建响应

      • 开发者使用HttpServletResponse对象设置响应的状态码、响应头、响应体等。
      • 可以向响应体写入HTML、JSON、XML等格式的数据。
    7. 发送响应

      • Servlet容器将HttpServletResponse对象封装成HTTP响应,并通过网络发送给客户端。
      • 客户端接收到响应后,会显示在Web浏览器上或进行其他处理。
    8. Servlet生命周期结束

      • 当Servlet实例不再需要时(如Web应用被卸载),容器会调用destroy方法,允许开发者进行资源清理工作。
        在Servlet API中,service 方法是Servlet容器(如Tomcat)用来调用特定HTTP方法处理程序的入口点。当客户端发送一个HTTP请求到Servlet容器时,容器会解析请求,确定它是哪种类型的HTTP方法(如GET、POST、PUT、DELETE等),然后调用相应的doXXX方法。

    service方法是一个重要的方法,它根据客户端发送的HTTP请求类型(如GET、POST等)调用相应的doXXX方法。以下是HttpServlet类中service方法的实现:

    @Override
    public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException {
    
        HttpServletRequest  request;
        HttpServletResponse response;
        try {
            // 将ServletRequest和ServletResponse强制转换为HttpServletRequest和HttpServletResponse
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException("Cannot cast to HttpServletRequest/HttpServletResponse");
        }
    
        // 获取HTTP请求方法
        String method = request.getMethod();
        if (method.equalsIgnoreCase("GET")) {
            // 如果是GET请求,调用doGet方法
            long lastModified = getLastModified(request);
            if (lastModified == -1) {
                // 标记响应不被缓存
                response.setDateHeader("Expires", -1);
                response.setHeader("Cache-Control", "no-cache");
                response.setHeader("Pragma", "no-cache");
            } else {
                // 检查If-Modified-Since头以判断是否发送304 Not Modified响应
                long ifModifiedSince = request.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // 资源已修改,发送新内容
                    maybeSetLastModified(response, lastModified);
                } else {
                    // 资源未修改,发送304 Not Modified响应
                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                    return;
                }
            }
            doGet(request, response);
        } else if (method.equalsIgnoreCase("HEAD")) {
            // 如果是HEAD请求,调用doHead方法
            long lastModified = getLastModified(request);
            maybeSetLastModified(response, lastModified);
            doHead(request, response);
        } else if (method.equalsIgnoreCase("POST")) {
            // 如果是POST请求,调用doPost方法
            doPost(request, response);
        } else if (method.equalsIgnoreCase("PUT")) {
            // 如果是PUT请求,调用doPut方法
            doPut(request, response);
        } else if (method.equalsIgnoreCase("DELETE")) {
            // 如果是DELETE请求,调用doDelete方法
            doDelete(request, response);
        } else if (method.equalsIgnoreCase("OPTIONS")) {
            // 如果是OPTIONS请求,调用doOptions方法
            doOptions(request, response);
        } else if (method.equalsIgnoreCase("TRACE")) {
            // 如果是TRACE请求,调用doTrace方法
            doTrace(request, response);
        } else {
            // 对于不支持的HTTP方法,抛出ServletException
            throw new ServletException("HTTP method " + method + " is not supported");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    这个service方法首先检查传入的ServletRequestServletResponse是否可以安全地强制转换为HttpServletRequestHttpServletResponse。接着,它获取HTTP请求的方法(如GET、POST等),并根据这个方法调用相应的doXXX方法。如果请求方法是GET,它还会检查If-Modified-Since头以判断是否发送304 Not Modified响应。

    对于不支持的HTTP方法,service方法会抛出一个ServletException。通常,开发者会覆盖doGetdoPost等方法来提供具体的业务逻辑,而service方法则负责调度这些方法。

    三、示例代码

    下面是一个简单的HttpServlet示例,展示了如何处理GET请求:

    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            // 设置响应内容类型
            response.setContentType("text/html;charset=UTF-8");
            
            // 实际的逻辑是在这里
            String message = "

    Hello, World!

    "
    ; // 将响应体写入到response对象中 response.getWriter().write(message); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这个示例中,MyServlet类继承了HttpServlet类,并重写了doGet()方法。当容器接收到一个GET请求时,它会调用doGet()方法来处理请求。在doGet()方法中,我们设置了响应的内容类型为HTML,并构建了一个简单的HTML消息作为响应体。

  • 相关阅读:
    抖音实战~分享模块~生成短视频二维码
    婚纱摄影行业,还在使用电梯广告?不如试试大数据精准营销
    2022-09-12 Lex and YACC primer/HOWTO
    解析Spring Cloud面试的十道难题,帮你攻克技术关卡
    PostgreSQL-存储过程使用入门
    【树莓派】windows和树莓派之间文件共享(Samba)
    Idea创建JavaEE项目
    一起Talk Android吧(第三百七十八回:给ViewPager添加indicator)
    艾美捷山羊抗人IgG-AP化学性质&曲线展示
    猿创征文|School StartsFirstProject~UnityVR(HTCVive设备开发)
  • 原文地址:https://blog.csdn.net/qq_32868023/article/details/136281197