【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…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
