当前位置: 首页 > news >正文

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和HttpServletResponserequest = (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方法,抛出ServletExceptionthrow new ServletException("HTTP method " + method + " is not supported");}
}

这个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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应内容类型response.setContentType("text/html;charset=UTF-8");// 实际的逻辑是在这里String message = "<html><body><h1>Hello, World!</h1></body></html>";// 将响应体写入到response对象中response.getWriter().write(message);}
}

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

相关文章:

  • 【蓝桥杯单片机入门记录】动态数码管
  • IDEA启动Springboot报错:无效的目标发行版:17 的解决办法
  • 【java】使用springMVC优雅的响应数据
  • 【Spring连载】使用Spring Data访问 MongoDB(十一)----加密Encryption (CSFLE)
  • 【加密算法】AES对称加密算法简介
  • 基于smilehappiness-framework-base,快速集成ShardingSphere JDBC
  • 请求包的大小会影响Redis每秒处理请求数量
  • linux部署nginx
  • 【JavaEE】_tomcat的安装与使用
  • Android Gradle 开发与应用 (一) : Gradle基础
  • spring Boot快速入门
  • Java MP3转PCM
  • 一文读懂什么是HTTPS检查
  • linux centos7.9改dns和ip
  • 【rust】vscode下rust-analyzer和Rust Test Lens的Lens
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • [笔记] php常见简单功能及函数
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • “大数据应用场景”之隔壁老王(连载四)
  • download使用浅析
  • React+TypeScript入门
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 从重复到重用
  • 如何设计一个比特币钱包服务
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 阿里云ACE认证之理解CDN技术
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • #include<初见C语言之指针(5)>
  • (07)Hive——窗口函数详解
  • (16)Reactor的测试——响应式Spring的道法术器
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (十五)使用Nexus创建Maven私服
  • (未解决)macOS matplotlib 中文是方框
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)Sublime Text3配置Lua运行环境
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .Net各种迷惑命名解释
  • @Conditional注解详解
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [APIO2012] 派遣 dispatching
  • [bbk5179]第66集 第7章 - 数据库的维护 03
  • [codeforces]Recover the String
  • [Grafana]ES数据源Alert告警发送
  • [GXYCTF2019]禁止套娃
  • [Java][Liferay] File system in liferay
  • [JS] 常用正则表达式集(一)
  • [LeetCode] Longest Common Prefix 字符串公有前序
  • [leetcode] Multiply Strings
  • [Linux] MySQL数据库之索引