Servlet原理Servlet API

目录

一、Servlet运行原理

1.1、问题

1.2、Servlet的具体执行过程

1.3、Tomcat初始化流程小结

1.4、Tomcat处理请求流程

二、Servlet API详解

2.1、HttpServlet类

2.1.1、处理Get请求

2.2、HttpServletRequest类

2.3、HttpServletResponse类

2.3.1、设置状态码

​2.3.2、自动刷新

2.3.3、重定向 


一、Servlet运行原理

1.1、问题

        在Servlet的代码中我们并没有写main方法,要知道一个程序的入口是main方法,那么没有main方式是如何被调用呢?响应又是如何返回给浏览器呢?

        当浏览器给服务器发送请求的时候,Tomcat作为HTTP服务器,就可以接收到这个请求

1.2、Servlet的具体执行过程

客户端发送请求->到Tomcat的webServer->Servlet管理器(多个)->Servlet实例

具体过程:

(1)接收请求

  1. 用户在浏览器输入一个URL,此时浏览器就会构造出一个HTTP请求;
  2. HTTP请求开始从应用层往下逐层封装数据(打包)得到一个二进制的bit流,最后通过物理层将数据传输给服务器端的物理层;
  3. 服务器端的物理层接收到数据之后,开始从物理层往上逐层分用,层层解析数据(解析),最终还原出HTTP请求,并交给Tomcat进程进行处理(根据端口号确定进程);
  4. Tomcat通过Socket读取到这个请求(一个字符串),并按照HTTP请求的格式来解析这个请求:根据请求中的Context Path确定一个webapp,再通过Servlet Path确定一个具体的类,再根据当前请求的方法(GET或者POST或其他)决定调用这个类的doGet或者doPost方法。此时我们的代码中的doGet或者doPost方法的第一个参数HttpServletRequest 就包含了这个 HTTP 请求的详细信息

(2)根据请求计算响应

        在我们的doGet或者doPost执行完毕之后,就执行到了我们自己的代码。我们的代码会根据请求中的一些信息,来给HttpServletResponse对象设置一些属性:比如状态码,header,body等。

(3)返回响应

  1. 等我们的doGet或者doPost执行结束之后,Tomcat就会自动将HttpServletResponse这个我们刚设置好的对象转化为一个符合HTTP协议的字符串,通过Socket将这个响应发送出去;
  2. 然后响应数据在服务器的主机上又通过网络协议栈层层封装,得到一个二进制的bit流,通过物理层将数据传输出去;
  3. 此时浏览器的物理层收到了响应数据,从下往上到应用层将数据进行分用,还原成HTTP响应,交给浏览器处理;
  4. 浏览器通过Socket读到这个响应(一个字符串),按照HTTP响应的格式来解析这个响应,并将body中的数据按照一定的格式显示在浏览器的界面上。

1.3、Tomcat初始化流程小结

  1. Tomcat的代码中内置了main方法,当我们启动Tomcat的时候,就是从Tomcat的main方法开始执行的;
  2. 被@webservlet注解修饰的类会在Tomcat启动的时候就会被获取到,并集中管理;
  3. Tomcat通过 反射 这样的语法机制来创建被 @WebServlet 注解修饰的类的实例;
  4. 这些实例被创建完了之后 , 会点调用其中的 init 方法进行初始化 . ( 这个方法是 HttpServlet 自带的 , 我们自己写的类可以重写 init);
  5. 这些实例被销毁之前 , 会调用其中的 destory 方法进行收尾工作 . ( 这个方法是 HttpServlet 自带的 , 我们自己写的类可以重写 destory);

1.4、Tomcat处理请求流程

  1. Tomcat Socket 中读到的 HTTP 请求是一个字符串, 然后会按照 HTTP 协议的格式解析成一个HttpServletRequest 对象;
  2. Tomcat 会根据 URL 中的 path 判定这个请求是请求一个静态资源还是动态资源. 如果是静态资源, 直接找到对应的文件把文件的内容通过 Socket 返回. 如果是动态资源, 才会执行到 Servlet 的相关逻辑.
  3. Tomcat 会根据 URL 中的 Context Path Servlet Path 确定要调用哪个 Servlet 实例的 service 方法.
  4. 通过 service 方法, 就会进一步调用到我们之前写的 doGet 或者 doPost

二、Servlet API详解

2.1、HttpServlet类

在写Servlet代码的时候,第一步是创建一个类,继承HttpServlet,并重写其中的方法

方法调用时机
init在HttpServlet实例化之后被调用一次
destroy在HttpServelet实例不再使用时调用一次
service收到HTTP请求时调用 (由service调用)
doGet收到GET请求时调用 (由service调用)
doPost收到POST请求时调用 (由service调用)
doPut / doDelete…收到对应请求时调用 (由service调用)

init方法:该方法是在tomcat首次收到了该类相关联的请求时,就会调用到HelloServlet,就需要先对HelloServlet进行实例化,后续在收到请求时,不必再实例化了,直接复用之前的HelloServlet实例即可,只执行一次

destroy方法:当HttpServlet实例不再使用时调用该方法,啥时候该实例就不再使用了?服务器只要不停止,该实例就一直被使用,只有当服务器停止后了,才会调用该方法,只执行一次

Tomcat有两种方式结束:

  1. 通过8005端口,给Tomcat发起特殊的请求,Tomcat就关闭了,这就能执行destory
  2. 直接杀死Tomcat进程,比如使用任务管理器关闭Tomcat服务器,才是就不能执行desstory方法

service方法:service中根据请求的类型不同,调用不同的方法,doGet,doPost方法等等,会执行多次,每收到一次HTTP请求就执行一次

面试题:谈谈Servlet的生命周期

  1. webapp刚被加载的时候,调用servlet的init方法
  2. 每次收到请求的时候,调用service方法
  3. webapp要结束的时候,调用destory方法

注意:HttpServlet的实例只是在程序启动时创建一次,而不是每次收到HTTP请求都重新创建实例

2.1.1、处理Get请求

1、直接在浏览器中,通过URL就能构造(GET请求最常用法)

2、通过postman构造Get请求

3、通过ajax构造Get请求

2.2、HttpServletRequest类

当Tomcat通过Socket API读取HTTP请求,并且按照HTTP协议的格式把字符串解析成HttpServletRequest对象

方法描述
String getProtocol()返回请求协议的名称和版本。
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。
String getContextPath()返回指示请求上下文的请求 URI 部分。
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串。
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 对象

注意:请求对象是服务器收到的内容, 不应该修改。因此上面的方法也都只是 "读" 方法, 而不是 "写"方法。

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;@WebServlet("/request")
public class RequestServlet extends HelloServlet{@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//显示告诉浏览器,你拿到的数据是htmlresp.setContentType("text/html");//调用req的各个方法,把得到的结果汇总到一个字符串中,统一返回到页面上StringBuilder respBody = new StringBuilder();//下列内容是在浏览器上按照html方式来展示的,此时\n在html中并不是换行//而我们需要使用<br>标签进行换行respBody.append(req.getProtocol()); //HTTP版本号respBody.append("<br>");respBody.append(req.getMethod()); //返回HTTP方法的名称respBody.append("<br>");respBody.append(req.getRequestURI()); //请求路径respBody.append("<br>");respBody.append(req.getContextPath()); //上下文路径respBody.append("<br>");respBody.append(req.getQueryString()); //QuertStringrespBody.append("<br>");//拼接header//获取请求的header头Enumeration<String> headers = req.getHeaderNames();while (headers.hasMoreElements()) {String headerName = headers.nextElement();respBody.append(headerName);respBody.append(": ");respBody.append(req.getHeader(headerName));respBody.append("<br>");}//统一返回结果resp.getWriter().write(respBody.toString());}
}

浏览器响应结果如下: 

2.3、HttpServletResponse类

Servlet中的doxxx方法的目的就是根据请求计算得到响应,然后把响应的数据设置到HttpServletResponse对象中,然后Tomcat就会把这个HttpServletResponse对象按照HTTP协议的格式转成一个字符串,并通过Socket写回到浏览器。

方法描述
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 中写入二进制格式数据

注意:响应对象是服务器要返回给浏览器的内容,这里的重要信息都是程序员设置的。因此上面的方法都是"写"方法。

注意:对于状态码/响应头的设置要放到getWriter/GetOutputStream之前,否则可能设置失效。

2.3.1、设置状态码

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/status")
public class StatusServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {//resp.setStatus(404);resp.setStatus(200);//返回Tomcat自带的错误页面resp.sendError(500);}
}

 2.3.2、自动刷新

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//告诉浏览器每隔2秒刷新一次resp.setHeader("refresh", "2");//返回系统时间resp.getWriter().write("time: " + System.currentTimeMillis());}
}

2.3.3、重定向 

实现一个程序,返回一个重定向HTTP响应,自动跳转到另一个页面

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/redirect")
public class Redirect extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//实现重定向,让浏览器自动跳转到百度浏览器resp.setStatus(302);//设置重定向,让浏览器自动跳转到百度resp.setHeader("Location", "https://www.baidu.com");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/296454.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二维码的生成、下载Java,并返回给前端展示

分析 将生成的二维码图片&#xff0c;以IO流的方式&#xff0c;通过response响应体直接返回给请求方。 第一、不需要落到我们的磁盘&#xff0c;操作在内存中完成&#xff0c;效率比较高。 第二、所有生成二维码的请求&#xff0c;都可以访问这里&#xff0c;前端直接拿img标…

【tools】Lokalise 可用于本地化各种类型的应用程序和网站

【tools】Lokalise 可用于本地化各种类型的应用程序和网站 1. Lokalise 基本功能2. Lokalise 可用于本地化各种类型的应用程序和网站,那部署的应用程序和网站运行再什么地方,数据存储再什么位置?https://app.lokalise.com/quick-start 1. Lokalise 基本功能 Lokalise 是一款…

RUST语言基本数据类型认识

1.RUST的基本数据类型参考: 2.使用RUST数据类型声明变量并赋值: let a:i81;//8位有符号整数let a1:u82;//8位无符号整数let b:i161;//16位有符号整数let b1:u162;//16位无符号整数let c:i321;//32位有符号整数let c1:u322;//32位无符号整数let d:i641;//64位有符号整数let d1:u…

Java零基础入门-java8新特性(上篇)

一、本期教学目标 java8有哪些新特性什么是函数式接口什么是Lambda表达式掌握Stream ApiStream和Collect集合区别Stream创建方式Stream操作三步骤 二、概述 上几期&#xff0c;我们是完整的学完了java异常类的学习及实战演示、以及学习了线程进程等基础概念&#xff0c;而这一…

VSCode调试C++

1、环境准备 1.1、g的安装与使用 1.1.1、安装 方式一&#xff1a;Xcode安装 苹果的开发集成工具是Xcode.app&#xff0c;其中包含一堆命令行工具。 在 App store 可以看到其大小有好几个G&#xff0c;有点大。 方式二&#xff1a;Command Line Tools 安装 Command Line Too…

算法知识点汇总

知识点 1. 求二进制中1的个数 int get_count(int x)//返回x的二进制有多少个1 int get_count(int x) {int res 0;while (x){res ;x - x & -x;}return res; }2. 建树&#xff0c;和树的DFS 记得初始化头节点 const int N 1e5 10, M N * 2; int h[N], e[M], ne[M], id…

【智能算法】猎豹优化器(CO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2022年&#xff0c;MA Akbari等人受到自然界中猎豹捕猎行为启发&#xff0c;提出了猎豹优化器&#xff08;The Cheetah Optimizer&#xff0c;CO&#xff09;。 2.算法原理 2.1算法思想 CO法对猎…

Shell GPT:直接安装使用的chatgpt应用软件

ShellGPT是一款基于预训练生成式Transformer模型&#xff08;如GPT系列&#xff09;构建的智能Shell工具。它将先进的自然语言处理能力集成到Shell环境中&#xff0c;使用户能够使用接近日常对话的语言来操作和控制操作系统。 官网&#xff1a;GitHub - akl7777777/ShellGPT: *…

使用vuepress搭建个人的博客(一):基础构建

前言 vuepress是一个构建静态资源网站的库 地址:VuePress 一般来说,这个框架非常适合构建个人技术博客,你只需要把自己写好的markdown文档准备好,完成对应的配置就可以了 搭建 初始化和引入 创建文件夹press-blog npm初始化 npm init 引入包 npm install -D vuepress…

【C++】C++11类的新功能

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 默认成员函数 类成…

Windows下编译TinyXML(XML文件解析)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 TinyXML是什么&#xff1f; TinyXML是一个轻量级的C XML解析器&#xff0c;它提供了一种简单的方法来解析和操作XML文档。TinyXM…

Camtasia Studio2024汉化版下载(功能强大的屏幕录制和视频编辑软件)

Camtasia Studio 2024是一款功能强大的屏幕录制和视频编辑软件&#xff0c;由TechSmith公司开发。这款软件不仅能够帮助用户轻松地记录电脑屏幕上的任何操作&#xff0c;还可以将录制的视频进行专业的编辑和制作&#xff0c;最终输出高质量的视频教程、演示文稿、培训课程等。 …

Termius for Mac v8.4.0激活版下载

Termius for Mac是一款功能强大的多协议远程管理软件&#xff0c;专为开发人员、系统管理员和网络专业人士设计。它支持多种远程连接协议&#xff0c;如SSH、Telnet、RDP、VNC和RFB等&#xff0c;使得用户可以轻松连接到不同类型的远程服务器和设备。 软件下载&#xff1a;Term…

企业家升维认知:引领企业持续发展的关键

一、引言 在快速变化的时代背景下&#xff0c;企业家面临着前所未有的挑战与机遇。新东方教育科技集团董事长俞敏洪曾深刻指出&#xff1a;“企业家本身要不断升维自己的认知&#xff0c;才能带领企业持续发展。”这句话不仅揭示了企业家认知升维的重要性&#xff0c;也为我们…

高效准确!指甲剪盖片视觉检测技术解密

指甲剪的盖片是指指甲剪的一端&#xff0c;通常用来盖住另一端的刀刃部分。指甲剪盖片是指甲剪的重要部分&#xff0c;除了保护刀刃外&#xff0c;还起到美观和便捷的作用。正确使用和保养指甲剪盖片可以延长指甲剪的使用寿命。 本案是对指甲剪盖片最大尺寸长75mm*宽10mm*高3mm…

蓝桥杯算法题:区间移位

题目描述 数轴上有n个闭区间&#xff1a;D1,...,Dn。 其中区间Di用一对整数[ai, bi]来描述&#xff0c;满足ai < bi。 已知这些区间的长度之和至少有10000。 所以&#xff0c;通过适当的移动这些区间&#xff0c;你总可以使得他们的“并”覆盖[0, 10000]——也就是说[0, 100…

vulnhub之devguru靶场提权过程(vulnhub打靶日记)

一、环境搭建 VM版本&#xff1a;17.5.1 build-23298084 攻击机&#xff1a;Kali2024&#xff08;下载地址&#xff1a;https://www.kali.org/&#xff09; 靶机&#xff1a;vulnhub靶场Devguru&#xff08;下载地址&#xff1a;https://www.vulnhub.com/entry/devguru-1,62…

RUST语言函数的定义与调用

1.定义函数 定义一个RUST函数使用fn关键字 函数定义语法: fn 函数名(参数名:参数类型,参数名:参数类型) -> 返回类型 { //函数体 } 定义一个没有参数,没有返回类型的参数 fn add() {println!("调用了add函数!"); } 定义有一个参数的函数 fn add(a:u32)…

llama.cpp运行qwen0.5B

编译llama.cp 参考 下载模型 05b模型下载 转化模型 创建虚拟环境 conda create --prefixD:\miniconda3\envs\llamacpp python3.10 conda activate D:\miniconda3\envs\llamacpp安装所需要的包 cd G:\Cpp\llama.cpp-master pip install -r requirements.txt python conver…

网络基础二——传输层协议UDP与TCP

九、传输层协议 ​ 传输层协议有UDP协议、TCP协议等&#xff1b; ​ 两个远端机器通过使用"源IP"&#xff0c;“源端口号”&#xff0c;“目的IP”&#xff0c;“目的端口号”&#xff0c;"协议号"来标识一次通信&#xff1b; 9.1端口号的划分 ​ 0-10…