【Servlet篇2】Servlet的工作过程,Servlet的api——HttpServletRequest
一、Servlet的工作过程
二、Tomcat的初始化
步骤1:寻找到当前目录下面所有需要加载的Servlet(也就是类)
步骤2:根据类加载的结果创建实例(通过反射),并且放入集合当中
步骤3:实例创建好之后,调用Servlet的init()方法初始化一些属性
步骤4:创建TCP的socket,并且监听8080端口,等待客户端建立连接
步骤5:关闭服务器的时候,需要调用Servlet的destory()方法
三、Tomcat处理请求
步骤1:根据socket构造请求的对象(req)以及响应的对象(resp)
步骤2:判断请求的资源是否是一个静态的页面
步骤3:根据请求的URL找到处理请求的Servlet
步骤4:根据Servlet对象,来调用service方法
最后:简单概括一下Servlet的生命周期:
doPost方法乱码问题:
四、Servlet的核心api
HttpServletRequest类
String getRequestURI()和String getRequestURL()
String getQueryString()
Enumeration getParameterNames()
String getParameter(String name)
String getHeader("name")
InputStream getInputStream()
String getContextPath()
一、Servlet的工作过程
需要了解的是,Sevlet是工作在应用层的,是一个应用程序。它是一个运行在用户态的的java进程。
第一步:客户端主机生产了http报文,然后经过一次封装,到达客户端的物理层。然后以光电信号的方式在网络当中传输。
第二步:服务端主机在收到了对应的光电信号之后,进行了一次数据从物理层到服务端的应用层的一次分用。
第三步:服务端计算客户端的响应,然后在把数据通过response对象回写给客户端。
二、Tomcat的初始化
步骤1:寻找到当前目录下面所有需要加载的Servlet(也就是类)
在这一篇文章当中,我们提到了如何把一个项目打包成一个war包。war包当中的文件都是.class为后缀名的。
然后把这一个war包放入到Tomcat的webapps目录下面。双击startup.bat就可以运行Tomcat了。
【Servlet篇2】创建一个web项目_革凡成圣211的博客-CSDN博客Tomcat的web项目https://blog.csdn.net/weixin_56738054/article/details/129265315?spm=1001.2014.3001.5501 然后tomcat就会从webapps里找到那些.class对应的Servlet类,进行加载。
可以看到,经过编译的Servlet,都变成了.class结尾的了。 伪代码实现:
public void start(){//第一步:通过Tomcat加载所有的.class结尾的文件Class<Servlet>[] allServletClasses=Tomcat.load();}
步骤2:根据类加载的结果创建实例(通过反射),并且放入集合当中
遍历上面的allServletClasses数组。并且在遍历的过程当中,每遍历一个,都通过反射创建一个Servlet的实例对象。创建完成之后,再次把这些实例添加到Servlet实例的集合当中。
伪代码实现:
/***这是一个存放Servlet实例的集合*/private final List<Servlet> instanceServlet=new ArrayList<>();public void start() throws InstantiationException, IllegalAccessException {//第一步:通过Tomcat加载webapps下面所有的.class结尾的文件Class<Servlet>[] allServletClasses=Tomcat.load();//第二步:根据类加载的结果创建Servlet的实例for(Class<Servlet> servletClass:allServletClasses){//根据class加载的结果,创建servlet的实例对象Servlet servlet= servletClass.newInstance();//把Servlet的实例对象存放到集合当中instanceServlet.add(servlet);}}
步骤3:实例创建好之后,调用Servlet的init()方法初始化一些属性
伪代码:
for(Servlet servlet:instanceServlet){//init方法默认情况下面什么都不做//但是可以初始化一些属性servlet.init();}
前面的文章当中,我们提到了,如果一个普通的类想成为Servlet,那就一定需要首先继承于HttpServlet。
当然,也可以由当前的类初始化一些属性,那就需要重写init()方法了。
每一个Servlet在启动的时候,都仅仅只会调用一次init()方法。
步骤4:创建TCP的socket,并且监听8080端口,等待客户端建立连接
在服务端,使用线程池的的方式来处理每一个请求。
在下面的伪代码当中,首先使用serverSocket监听8080端口。
然后服务端重复调用accept()方法等待客户端建立连接
并且使用往线程池当中提交任务的方式来处理请求。
伪代码实现:
//这个socket是服务端TCP的socket,创建的时候默认占用8080端口ServerSocket serverSocket=new ServerSocket(8080);//使用线程池,添加任务ExecutorService service= Executors.newFixedThreadPool(10);while (true){//每当有一个客户端与当前的服务端建立连接的时候,就会监听8080端口//accept()一次Socket socket=serverSocket.accept();//向线程池提交任务service.execute(new Runnable() {@Overridepublic void run() {doHttpRequest(socket);}});}
其中,doHttpRequest方法内部,就是解析客户端发送请求的方法。也就是执行doGet被调用的过程。
步骤5:关闭服务器的时候,需要调用Servlet的destory()方法
伪代码实现:
//关闭服务器,销毁servletfor(Servlet servlet:instanceServlet){servlet.destroy();}
总览一下:Tomcat初始化的过程:
三、Tomcat处理请求
刚刚提到了,在doHttpServletRequest方法当中,是对于socket进行处理的过程。
下面,继续通过伪代码的方式,来解析一下具体是怎样处理请求的。
步骤1:根据socket构造请求的对象(req)以及响应的对象(resp)
对于request:首先读取socket当中的数据,然后再按照HTTP协议的格式来返回。
对于response:仅仅只是构造了一个空的对象,还没有填充响应的信息
伪代码:
private void doHttpRequest(Socket socket) {//对于request,首先读取socket当中的数据,然后再按照HTTP协议的格式来返回HttpServletRequest request=HttpServletRequest.parse(socket);//构造一个没有填充数据是responseHttpServletResponse response=HttpServletResponse.build(socket);}
步骤2:判断请求的资源是否是一个静态的页面
伪代码:
如果请求的资源是一个静态的页面,例如:https:....../.html这样的页面。那么就读取文件的内容,并且把文件的内容构造的resp对象当中。
【网络原理9】HTTP响应篇_革凡成圣211的博客-CSDN博客HTTP响应,HTTP状态码https://blog.csdn.net/weixin_56738054/article/details/129208502?spm=1001.2014.3001.5502 在HTTP响应篇这一篇文章当中提到了:HTTP响应头当中有一个属性代表的是返回的资源的类型(content type属性)。如果是一个静态的html页面,那么这个类型的值就是test/html
//访问的资源是一个静态的页面if(file.exists()){//通过response返回这一个页面return;}
步骤3:根据请求的URL找到处理请求的Servlet
伪代码:
//通过请求的URL路径,返回Tomcat加载的对应的那一个Servlet
Servlet ins=findInstance(request.getRequestURL());
例如一个请求是:localhost:8080/hello106/hello。
那么这个hello代表的就是一个Servlet。
步骤4:根据Servlet对象,来调用service方法
伪代码:
try {//调用service方法ins.service(request,response);}catch (Exception e){}
其实在service方法内部,就是根据request的请求来判断当前的请求的方法是属于get还是post
如果是get请求,那么就交给doGet方法来进行处理。
如果是post请求,那么就交给doPost方法来及逆行处理。
下面,通过一张图,来总览一下Tomcat处理请求的各个步骤
最后:简单概括一下Servlet的生命周期:
当被tomcat初始化的时候:调用init方法完成一些属性的初始化操作;
当执行具体逻辑的时候:调用service方法,然后在内部判断是doGet还是doPost方法;
当执行完毕的时候:调用destroy方法销毁。
doPost方法乱码问题:
在一个类当中,首先让一个类继承于HttpServlet这一个类,然后重写doPost方法。
并且通过resp.getWriter().write(字符串内容);来在页面上面输出一段话:
/*** @author 革凡成圣211*/
@WebServlet("/method")
public class Servlet2 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("POST响应");}
}
然后在前端页面当中通过post来提交请求(注意不可以直接在url地址栏当中输入,否则默认是get)
但是看到,此处的中文出现了乱码:
首先,分析一下,在当前的场景当中,字符串生成的两个环节:
环节1:生成(idea里面通过硬编码的方式把这个字符串写进去)
环节2:展示(浏览器把这个字符串显示到控制台当中)
如果以上的两个操作不一致,那么就比较容易出现乱码。
对于环节2,浏览器展示的时候,一般都是默认使用windows简体的中文版,默认是gbk。
对于环节1,idea编码的方式一般都是使用utf-8。
为了统一idea和浏览器的编码方式,可以改变浏览器的读取的编码规则,让浏览器按照utf-8来读取。
/*** @author 革凡成圣211*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置响应头的响应格式,以及字符集编码方式resp.setContentType("text/html; charset=utf8");resp.getWriter().write("POST"+"响应");}
}
也就是把HTTP响应头当中的两个键值对,一个是content-type,另外一个是charset。
不过,也有更简单的方式来发送post请求,那就是使用postman。
HttpServletRequest类
每一个HttpServletRequest代表一个HTTP请求。也就是一个HTTP请求当中包含什么内容,那么一个HttpServletRequest就封装了什么内容。
在这一篇文章当中,我们提到了:使用Fiddler抓包的时候,提到了一个HTTP请求是由三部分组成的:【网络原理7】认识HTTP_革凡成圣211的博客-CSDN博客HTTP抓包,Fiddler的使用https://blog.csdn.net/weixin_56738054/article/details/129148515?spm=1001.2014.3001.5502
第一部分:请求行(URL)
第二部分:请求头(多组键值对)
第三部分:请求的body
那么,通过一个HttpServletRequest同样也可以获取到一个HTTP请求当中的各类信息。
下面,介绍几个HttpServletRequest的几个常用方法:
String getRequestURI()和String getRequestURL()
假如我想访问的资源是:http://localhost:8080/ServletLearning_war_exploded/hello
方法名称 | 返回 | 含义 |
String getRequestURI() | "/ServletLearning_war_exploded/hello" | 除了域名+端口号往后的内容,也就是需要访问的具体是哪一个文件 |
String getRequestURL() | "http://localhost:8080/ServletLearning_war_exploded/hello" | 一个完整的请求路径 |
需要注意的是,无论是URI还是URL,请求路径当中如果包含了queryString(查询字符串)
那么都无法在上述两个方法当中返回。
String getQueryString()
这个方法,仅仅在URL地址栏当中包含queryString的时候,才会生效。
假如我想访问呢的URL地址为:
http://localhost:8080/ServletLearning_war_exploded/hello?key=666
可以看到,在上述的URL当中,携带了一个queryString,那就是key=666。
所以上述方法返回的就是:
"key=666"这一个字符串
Enumeration getParameterNames()
也是在请求栏当中存在queryString的时候生效。得到的所有key,都是以枚举的方式来列举的
String getParameter(String name)
根据根据queryString的key来获取到value。
String getHeader("name")
这一个方法是获取HTTP请求头当中多组键值对中,其中以"name"为key的value。
例如: req.getHeader("Content-Type")
那么,这个方法就是返回Content-Type的值是什么
例如在上述的方法当中,返回的内容就是:application/x-www-form-urlencoded
InputStream getInputStream()
可以通过这个输入流对象,读取到HTTP请求的body部分的内容。
String getContextPath()
这一个方法返回的是一个项目的名称:
例如一个URL请求为:http://localhost:8080/ServletLearning_war_exploded/hello
那么返回的内容就是:/ServletLearning_war_exploded
相关文章:

【Servlet篇2】Servlet的工作过程,Servlet的api——HttpServletRequest
一、Servlet的工作过程 二、Tomcat的初始化 步骤1:寻找到当前目录下面所有需要加载的Servlet(也就是类) 步骤2:根据类加载的结果创建实例(通过反射),并且放入集合当中 步骤3:实例创建好之后,调用Servlet的init()方…...

【JAVASE】注解
文章目录1.概述2.JDK内置注解2.1override注解2.2 Deprecated注解3.元注解4.注解中定义属性4.1 属性value4.2 属性是一个数组5. 反射注解6.注解在开发中的作用1.概述 注解,也叫注释,是一种引用数据类型。编译后也同样生成class字节码文件。 语法 [修饰…...

【408之计算机组成原理】计算机系统概述
目录前言一、计算机的发展历程1. 计算机发展的四代变化2. 计算机元件的更新换代3. 计算机软件的发展二、计算机系统层次结构1. 计算机系统的组成2. 冯诺依曼体系结构3. 计算机的功能部件1. 输入设备2. 输出设备3. 存储器4. 运算器5. 控制器三、 分析计算机各个部件在执行代码中…...

1.Spring Cloud (Hoxton.SR10) 学习笔记—基础知识
本文目录如下:一、Spring Cloud基础知识什么是微服务架构?服务拆分 有哪些注意事项?什么是分布式集群?分布式的 CAP 原则?组件 - Spring Cloud 哪几个组件比较重要?组件 - 为什么要使用这些组件?组件 - Na…...

嵌入式开发工具箱【持续更新中】【VMware、Ubuntutftp、nfs、SecureCRT、XShell、Source Insight 4.0】
一、概述 本文主要介绍嵌入式开发过程中需要用到的工具及简单的使用方法。避免在搭建嵌入式开发环境时,需要四处寻找文档,收藏此文章,一文搞定。 大多数嵌入式开发环境是使用Linux作为目标开发系统,所以开发主机一般都是Linux系统…...

深究Java Hibernate框架下的Deserialization
写在前面 Hibernate是一个开源免费的、基于 ORM 技术的 Java 持久化框架。通俗地说,Hibernate 是一个用来连接和操作数据库的 Java 框架,它最大的优点是使用了 ORM 技术。 Hibernate 支持几乎所有主流的关系型数据库,只要在配置文件中设置好…...

微服务一 实用篇 - Docker安装
《微服务一 实用篇 - Docker安装》 提示: 本材料只做个人学习参考,不作为系统的学习流程,请注意识别!!! 《微服务一 实用篇 - Docker安装》《微服务一 实用篇 - Docker安装》0.安装Docker1.CentOS安装Docker1.1.卸载(可选)1.2.安装docker1.3.启动docker…...

JavaSE22-集合2-map
文章目录一、集合概念二、map集合1、Map集合的特点2、HashMap2.1 HashMap特点2.2 创建对象2.3 常用方法2.4 遍历2.4.1 使用entrySet遍历2.4.2 使用keySet遍历3、HashMap的key去重原理一、集合概念 集合就是用于存储多个数据的容器。相对于具有相同功能的数组来说,集…...

【项目精选】病历管理系统设计与实现(源码+视频)
点击下载源码 企业财务管理系统主要用于电子病历来提高医院各项工作的效率和质量,促进医学科研、教学;减轻各类事务性工作的劳动强度,使他们腾出更多的精力和时间来服务于病人。本系统结构如下: 电子病例系统: 病人登…...

如何用Python把篮球和鸡联系起来
文章目录画个球让球转起来画个球 不管篮球和不和鸡联系起来,都首先得有个球,或者说要有一个球面,用参数方程可以表示为 xrcosϕcosθyrcosϕsinθzrsinϕ\begin{aligned} x & r\cos\phi\cos\theta\\ y & r\cos\phi\sin\th…...

【RocketMQ】消息的刷盘机制
刷盘策略 CommitLog的asyncPutMessage方法中可以看到在写入消息之后,调用了submitFlushRequest方法执行刷盘策略: public class CommitLog {public CompletableFuture<PutMessageResult> asyncPutMessage(final MessageExtBrokerInner msg) {// …...

AMBA-AXI(一)burst 传输-INCR/WRAP/Fixed
💡Note:本文是根据AXI协议IHI0022F_b_amba_axi_protocol_spec.pdf(issue F)整理的。主要是分享AXI3.0和4.0部分。如果内容有问题请大家在评论区中指出,有补充或者疑问也可以发在评论区,互相学习ὤ…...

Java知识复习(八)Spring基础
1、什么是Spring框架? Spring :是一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性 2、Spring、SpringMVC和SpringBoot的区别 Spring主要指Spring Framework,就是指如上图所示的各项功能模块Spr…...
WuThreat身份安全云-TVD每日漏洞情报-2023-02-27
漏洞名称:OTFCC 缓冲区错误漏洞 漏洞级别:中危 漏洞编号:CVE-2022-35060,CNVD-2023-11996,CNNVD-202209-1527 相关涉及:OTFCC OTFCC 漏洞状态:EXP 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2022-23648 漏洞名称:MuYucms 存在任意代码执行漏洞 漏洞级别:高危…...

上海交大陈海波教授、夏虞斌教授领衔巨作上市:《操作系统:原理与实现》
❤️作者主页:小虚竹 ❤️作者简介:大家好,我是小虚竹。2022年度博客之星评选TOP 10🏆,Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作…...
dpi数据接入shell脚
原文:dpi数据接入shell脚本_weixin_34416754的博客-CSDN博客 ##############从ftp服务器拿数据文件 #!/bin/bash #获取感知优良率DPI数据 #DCN服务器信息 uSichuan pS988188# ip137.192.5.53 #获取日期,根据日期抓取文件 Tdate -d "3 days ago&…...

Easyrecovery数据恢复软件工作原理及使用介绍教程
Easyrecovery是一款强大的数据恢复软件,它专门解决磁盘数据恢复问题。在计算机世界里,数据丢失经常是一件令人头疼的事情,但是有了Easyrecovery,您可以放心大胆地享受数据备份和恢复的乐趣。EasyRecovery使用Ontrack公司复杂的模式…...

【面试题】社招中级前端笔试面试题总结
大厂面试题分享 面试题库后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库typeof null 的结果是什么,为什么?typeof null 的结果是Object。在 JavaScript 第一个版本中,所有值都存储在…...

设备运行状况不能远程手机查看。难道就妥协吗?为何不试试这个办法
一、背景 随着国家经济结构逐步调整,纺织行业自动化、智能化水平逐步提高,业内竞争程度也将加大;整个市场变化快,并呈现出智能化、通用化、网络化、复杂化的新发展趋势。客户订单小批量、个性化、快速交货的特点越来越明显&#…...

重新认识 Java 中的内存映射(mmap)
mmap 基础概念 mmap 是一种内存映射文件的方法,即将一个文件映射到进程的地址空间,实现文件磁盘地址和一段进程虚拟地址的映射。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页到对应的文…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...