【JavaWeb】Servlet 详解(处理逻辑及常见方法)
文章目录
- 1. Tomcat
- 1.1 常见的错误
- 1.1.1 出现 404
- 1.1.2 出现 405
- 1.1.3 出现 500
- 1.2 HttpServlet
- 1.2.1 Tomcat 的处理逻辑
- 1.2.2 相关方法
- 1.3 HttpServletRequest
- 1.3.1 常见方法
- 1.3.2 jackson 处理逻辑
- 1.4 HttpServletResponse
- 1.4.1 常见方法
1. Tomcat
tomcat 是一个 HTTP 服务器程序,对 HTTP 协议进行了封装,提供了一组 API,即 Servlet
开发者自己写的代码(类),会被加载到 Tomcat 中,Tomcat 接收到请求就会执行开发者写的代码,来完成相应的业务逻辑
Maven 是一个项目构建工具,可以进行项目的依赖的管理,代码编译和打包
tomcat 收到请求之后,就有可能执行子类中的方法,HttpServletRequest 对象是 Tomcat 解析请求后构造好的对象,HttpServletResponse 对象是个输出型参数
war 是 Tomcat 专属的压缩包,不仅有 .class 文件,还有 web.xml 等 Tomcat 要求的文件以及前端代码。
Tomcat 加载 webapp 的时候,用的是自定义的类加载器,只在 webapp 指定目录中查找,找不到就抛异常,不会去标准库中查找
1.1 常见的错误
1.1.1 出现 404
- url 路径有问题
- webapp 没有正确加载(如 web.xml 有问题)
1.1.2 出现 405
- 请求的方法与实际写的方法不一致(如前端请求 GET,但后端写的是 POST)
- 没有删掉super.doGet(req, resp),导致 HTTP 响应的格式出现了问题,浏览器无法正常解析
1.1.3 出现 500
- 服务器内部出错
1.2 HttpServlet
写 Servlet 的代码,并不需要写 main 方法,而是直接重写 HttpServlet 中的相关方法即可,Tomcat 中有 main 方法,也可以视为是一个框架。
继承 HttpServlet,重写其中的方法,就是为了将自己的代码插入到 Tomcat 中
1.2.1 Tomcat 的处理逻辑
// 通过 TCP Socket 读取请求
String requestString = readRequest();// 解析请求
HttpServletRequest req = parse(requestString);// 构造响应对象
HttpServletResponse resp = new HttpServletResponse();// 创建一个 HttpServlet 对象
HttpServlet s = new 自己写的Servlet子类();
s.doGet(req, resp);//将得到的响应 resp 返回给浏览器// ...
1.2.2 相关方法
| 方法名 | 调用时机 | 作用 |
|---|---|---|
| init | 在 HttpServlet 实例化之后被调用一次 | 完成初始化 |
| destroy | 在 HttpServlet 实例不再使用的时候调用一次(HttpServlet 被销毁之前) | 释放资源(若直接在任务资源管理器中结束任务,则来不及调用 destroy,若通过 8005 管理端口给 Tomcat 发送一个 “停机” 指令,则会执行 destroy,大多数情况下会直接杀进程) |
| service | 收到 HTTP 请求的时候调用 | 根据不同的方法将请求分发给 doGet、doPost 等 |
| doGet | 收到 Get 请求的时候被调用 | 计算 Get 请求的响应 |
| doPost | 收到 Post 请求的时候被调用 | 计算 Post 请求的响应 |
前三个方法体现了 Servlet 的生命周期
1.3 HttpServletRequest
Tomcat 通过 Socket API 读取 HTTP 请求(字符串),并且按照 HTTP 协议的格式将字符串解析成 HttpServletRequest 对象
1.3.1 常见方法
| 方法名 | 解释 |
|---|---|
| String getProtocol() | 返回请求协议的名称和版本 |
| String getMethod() | 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT |
| String getRequestURI() | 从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分 |
| String getContextPath() | 返回指示请求上下文的请求 URI 部分 |
| String getQueryString() | 返回查询字符串 |
| Enumeration getParameterNames() | 返回一个 String 对象的枚举,包含在该请求中包含的参数的名称 |
| String getParameter(String name) | 以字符串形式返回请求参数的值,或者如果参数不存在则返回 null |
| String[] getParameterValues(String name) | 返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null |
| Enumeration getHeaderNames() | 返回一个枚举,包含在该请求中包含的所有的头名 |
| String getHeader(String name) | 以字符串形式返回指定的请求头的值 |
| String getCharacterEncoding() | 返回请求主体中使用的字符编码的名称 |
| String getContentType() | 返回请求主体的 MIME 类型,如果不知道类型则返回 null |
| int getContentLength() | 以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1 |
| InputStream getInputStream() | 用于读取请求的 body 内容. 返回一个 InputStream 对象(得到一个流对象,读取这个流对象就能得到整个请求的 body,不必一次性处理完所有数据,可以一次处理一点,也可以一次处理完全部) |
| Cookie[] getCookies() | 获取到请求中的所有 Cookie |
| HttpSession getSession() | 从 Cookie 中获取到 sessionId,并查询出对应的 session。若未查到,就自动创建 session,分配新的 sessionId,创建新的 HttpSession 对象,将 sessionId 和 HttpSession 存入 hash 表中,并将 sessionId 添加到响应报文的 header 中(Set-Cookie 字段) |
在代码中表示一个 “不定长” 的数据时,经常会想到使用 “流对象”
1.3.2 jackson 处理逻辑
将 json 字符串转为 Java 对象,或将 Java 对象转为 json 字符串
// 将 json 字符串转为 Java 对象
Request request = objectMapper.readValue(req.getInputStream(), Request.class);
-
json 字符串是在 http 的 body 中,需要通过 HttpServletRequest 的 getInputStream 获取到,直接将 流对象 传给 readValue, readValue 内部会读取 InputStream 中的所有数据(http 请求的 body)
-
将 json 字符串按照 json 的格式解析成 Map(键值对)
-
将 Map 转换成 java 对象(通过 Request.class 告诉 readValue 方法,将 Map 转成什么对象)
-
readValue 内部,通过反射 API 创建 Request.class 实例,并根据其中的属性名来查询 Map,将查询结果赋值给相应的属性
jackson 只会处理 public 的属性
// 将 Java 对象转为 json 字符串
String respJson = objectMapper.writeValueAsString(response)
- 通过参数 response 获取到类对象,再通过反射拿到属性名字
- 根据属性名拿到属性值
- 根据属性名和属性值构造 json 格式的字符串
1.4 HttpServletResponse
1.4.1 常见方法
| 方法名 | 解释 |
|---|---|
| void setStatus(int sc) | 为该响应设置状态码 |
| void setHeader(String name, String value) | 设置一个带有给定的名称和值的 header。如果 name 已经存在,则覆盖旧的值 |
| void addHeader(String name, String value) | 添加一个带有给定的名称和值的 header。如果 name 已经存在,不覆盖旧的值, 并列添加新的键值对 |
| void setContentType(String type) | 设置被发送到客户端的响应的内容类型 |
| void setCharacterEncoding(String charset) | 设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8 |
| void sendRedirect(String location) | 使用指定的重定向位置 URL 发送临时重定向响应到客户端 |
| PrintWriter getWriter() | 往 body 中写入文本格式数据 |
| OutputStream getOutputStream() | 用于往 body 中写入二进制格式数据 |
| void addCookie(Cookie cookie) | 向响应中添加指定的 cookie(添加到了浏览器中) |
session 不是持久化存储的
- 将会话进行持久化保存(文件、数据库、redis)
- 使用令牌的方式,将用户信息在服务器端加密,保存在浏览器
相关文章:
【JavaWeb】Servlet 详解(处理逻辑及常见方法)
文章目录 1. Tomcat1.1 常见的错误1.1.1 出现 4041.1.2 出现 4051.1.3 出现 500 1.2 HttpServlet1.2.1 Tomcat 的处理逻辑1.2.2 相关方法 1.3 HttpServletRequest1.3.1 常见方法1.3.2 jackson 处理逻辑 1.4 HttpServletResponse1.4.1 常见方法 1. Tomcat tomcat 是一个 HTTP 服…...
6 自研rgbd相机基于rk3566之深度计算库程序详解
自研rgbd相机基于rk3566之深度计算库详解 1 tof深度计算库框架读入深度图像参数配置tof模组标定参数读入及解析深度计算函数接口2 tof深度计算库程序详解深度计算程序头文件深度计算程序 源文件1 tof深度计算库框架 读入深度图像参数配置 支持raw8/raw10/raw16 格式 /*******…...
分布式系统框架hadoop3入门
分布式系统框架hadoop3入门 (qq.com) Hadoop3作为分布式系统架构的重要基石,为大规模数据存储与处理提供了强大支持 基本信息 hadoop:一个存储和处理大数据的分布式系统框架 组成: HDFS(数据存储)、MapReduce&…...
使用 i3.LayoutCell() 方法绘制版图并输出为 GDS 文件
使用 i3.LayoutCell 方法绘制版图并输出为 GDS 文件 引言正文引言 在 IPKISS i3.SRef() 函数 一文中我们介绍了如何使用 i3.SRef() 函数将 instance 对象添加到 i3.LayoutCell() 创建的 Cell 对象上。但是当我们使用 write_gdsii() 输出版图时代码就会报错。这里我们将介绍如何…...
mariadb容器
下载镜像 $ sudo docker pull mariadb启动容器 $ sudo docker run --name my-mariadb -d -e MARIADB_DATABASEtestdb -e MARIADB_ROOT_PASSWORDLetmein -p 3306:3306 mariadb上面命令会启动一个名为my-mariadb的容器,并初始化一个testdb数据库,同时设置…...
应用层协议Http
Http协议 1.1 什么是http协议 在进行网络通信时,应用层协议一般都是程序员自己写的,但是有一些大佬其实已经定义出了一些现成的应用层协议,例如:HTTP(超文本传输协议)、FTP(文件传输协议&#…...
display flex 的div 被子元素撑开不显示滚动条的一个解决demo
display flex 的div 被子元素撑开,不显示y轴滚动条的 一个解决demo。 注: 不一定适用所有人的的相同问题 less # less .contact {display: flex;flex-grow: 1;overflow: hidden auto;flex-direction: column;.contact-items {flex: 1 1 0;display: flex…...
判断键盘输入是数字、大写字母还是小写字母——C#学习笔记
以下代码将判断键盘输入字符是数字 还是字母: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp4 {using System;using System.Threading;public class BoolKeyTest{sta…...
进程控制块PCB的组织方式有哪些?
进程控制块(PCB,Process Control Block)是操作系统用来管理和跟踪进程的一个数据结构,它保存了与进程相关的各种信息。PCB 是操作系统调度进程的核心数据结构,通常通过某种组织方式进行管理。常见的 PCB 组织方式主要有…...
getent passwd 获取linux并显示用户账户信息
getent passwd 命令在Unix和类Unix系统(如Linux)中用于从系统的密码数据库(通常是/etc/passwd文件,但在某些配置中可能是通过网络服务如NIS或LDAP)中获取并显示用户账户信息。这个命令的输出列出了系统上所有用户的详细…...
达梦数据库+JPA+Springboot 报错 :无效的列名
文章目录 0、 开发环境1、需求说明2、适配过程3、问题描述和解决3.1报错问题3.2 问题解决 0、 开发环境 开发环境: idea 2022 SpringBoot版本 :2.7.1 JDK 111、需求说明 适配国产化数据库达梦8 2、适配过程 参考 Springboot jpa 达梦 3、问题描述…...
#单片机基础 笔记一
--单片机概述STM32开发环境搭建创建工程 --STM32-GPIO(重点)编程 --STM32-USART串口应用 --STM32-SPI(液晶屏)中断系统 --STM32-时钟系统(重点中的重点) --STM32-PWMADC --STM32-DMA DHT11 1. 计算机组成原理 1.1 计算机的组成 1…...
echarts多个环形图
echarts图表集 var dataValue [{name:今日待分配方量,value:49}, {name:今日已分配方量,value:602}, {name:今日完成方量,value:1037}]var piedata1 [{name: 1#拌和机,value: 20},{name: 2#拌和机,value: 22},{name: 3#拌和机 ,value: 17},{name: 4#拌和机,value: 18},{name…...
vue 的面试题
一、Html篇 1、常用的块级元素及行内元素有哪些? 块级元素:div、p、h1~h6、ol、ul、li、table、form 行内标签:a、span、img、input、lable、button 行内块元素:img、input、button 2、行内元素和块级元素的区别? 块级…...
MongoDB-部署PSA(一主一从一仲裁)架构复制集群
目录 环境信息环境准备mongoDB配置&部署复制集群搭建 环境信息 IP端口节点10.0.0.127017主10.0.0.227017从10.0.0.327017仲裁 环境准备 1.关闭THP Transparent Huge Pages 简称 THP。透明大页面(THP)是一种Linux内存管理系统,通过使用…...
CSS中 特殊类型的选择器 伪元素如何使用
一、什么是伪元素 在 CSS 中,伪元素是一种特殊类型的选择器,它允许你为元素的特定部分添加样式,而这些部分在 HTML 文档中并不实际存在。伪元素通常用于创建装饰性效果,如添加边框、背景、阴影等,而不需要额外的 HTML…...
科技信贷业务怎么寻找客户?
在科技信贷业务领域,寻找客户的痛点主要集中在以下几个方面: 1.风险评估难题:科技型企业尤其是初创企业,往往缺乏足够的历史数据和抵押物,这使得金融机构在评估其信用风险时面临较大挑战。由于科技企业的研发周期长、…...
VM中创建CentOS 7及VM中如何修改DHCP的IP网段
一、创建虚拟机 1新建Centos虚拟机 2类型选择 3版本兼容性选择 4镜像选择 5安装系统选择 6虚拟机的创建路径(选择C盘以外且不包含中文名称的路径) 7硬件配置选择 网络类型的选择(通常情况下选择NAT模式) 8剩下的全部按推荐走&…...
mybatis#{}与${}的区别,mybatis关联查询,mybatis动态sql
1.#{}与${}的区别 #{}是占位符,是采用预编译的方式向sql中传值,可以防止sql注入如果我们往sql中传值,可以使用这个,例如这个delete语句 ${}将内容直接拼接到sql语句中,一般不用于传值,可以当作列名&#x…...
K8S(Kubernates) 知识目录
1. 一文了解K8S(Kubernates) 2. K8S CNI CRI CSI 3. K8S Helm 4. K8S Harbor 5. K8S Operator 6. K8S 服务网格 7. K8S 存储 8. K8S 容器调度 9. K8S 探针 10. K8S Watch 11. K8S 版本发版 12. K8S 资源管理CPU&内存 13. K8S Flannel 1…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
