HTTP协议Request

news2024/11/23 20:56:41

文章目录

  • HTTP协议
    • 介绍
      • 概念
      • 版本
      • 分类
      • 特点
    • 浏览器抓包观察请求报文协议
      • 步骤
      • 实现
  • Request和Response概述
  • Request对象
    • Request继承体系
    • Request获取请求数据
      • 获取请求行数据
      • 获取请求头数据
      • 获取请求体数据
      • 获取请求参数(通用方式)
    • 解决post请求乱码问题
      • 解决思路
      • 解决方案
    • Request请求转发(前后端分离后使用较少,面试考)
      • 概述
      • 实现方式
      • 请求转发资源间共享数据:使用request域对象
      • 请求转发特点
    • Request的生命周期

HTTP协议

介绍

概念

超文本传输协议,是互联网上应用最为广泛的一种网络协议
简而言之:浏览器和服务器数据交换固定的格式

版本

http1.1:长连接,多个请求共用一个连接

分类

  1. 请求报文协议(浏览器发送给服务器的数据)
    1. 请求行
    2. 请求头
    3. 请求体
  2. 响应报文协议(服务器发送给浏览器的数据)
    1. 响应行
    2. 响应头
    3. 响应体

特点

  1. 先有请求
  2. 再有响应
  3. 一个请求对应一个响应

浏览器抓包观察请求报文协议

步骤

  1. 创建html页面
  2. 在html页面书写html代码
  3. 创建servlet
  4. 在servlet中书写java代码
  5. 启动服务器
  6. 打开浏览器,在浏览器访问页面,然后按F12,点击网络(network)
  7. 抓包结果分析

实现

  • html代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h2>GET请求</h2>
<form action="/getServlet" method="get">
    用户名:<input type="text" name="username" value="zhangsan" /><br>
    密码:<input type="text" name="pwd" value="123" /><br>
    <input type="submit" value="提交"/>
</form>


<h2>POST请求</h2>
<form action="/postServlet" method="post">
    用户名:<input type="text" name="username" value="zhangsan"/><br>
    密码:<input type="text" name="pwd" value="123"/><br>
    <input type="submit" value="提交"/>
</form>

</body>
</html>
  • java代码
package com.itheima.sh.d_http_04;

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("/getServlet")
public class GetServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("get....");
    }
}



package com.itheima.sh.d_http_04;

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("/postServlet")
public class PostServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("post....");
    }
}
  • 点击网络

Snipaste_2024-05-02_14-31-26.png

  • 抓包结果分析

请求报文协议.bmp

Request和Response概述

  1. service方法的两个参数request和response是由tomact创建的
  2. request表示请求数据,tomact将浏览器发送过来的请求数据解析并封装到request对象中
    1. servlet开发者可以通过request对象获得请求数据
  3. response表示响应数据,服务器发送给浏览器的数据
    1. servlet开发者可以通过response对象设置响应数据

request:获取请求数据

  • 浏览器会发送HTTP请求到后台服务器[Tomcat]
  • HTTP的请求中会包含很多请求数据[请求行+请求头+请求体]
  • 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中
  • 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数
  • 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务

response:设置响应数据

  • 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据
  • 把响应数据封装到response对象中
  • 后台服务器[Tomcat]会解析response对象,按照[响应行+响应头+响应体]格式拼接结果
  • 浏览器最终解析结果,把内容展示在浏览器给用户浏览

初步体验:

@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用request对象 获取请求数据
        String name = request.getParameter("name");//url?name=zhangsan

        //使用response对象 设置响应数据
        response.setHeader("content-type","text/html;charset=utf-8");
        response.getWriter().write("<h1>"+name+",欢迎您!</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Post...");
    }
}

浏览器访问:
Snipaste_2024-05-02_15-30-40.png

Request对象

Request继承体系

Snipaste_2024-05-02_15-34-15.png
从java ee-api中可以查看到Servlet和HttpServletRequest两个都是接口,接口是无法创建对象的,那么service和doGet还有doPost方法中参数的对象是由谁创建的呢?
这个时候,我们就需要用到Request继承体系中的RequestFacade:

  • 该类实现了HttpServletRequest接口,也间接实现了ServletRequest接口。
  • Servlet类中的service方法、doGet方法或者是doPost方法最终都是由Web服务器[Tomcat]来调用的,所以Tomcat提供了方法参数接口的具体实现类,并完成了对象的创建
  • 要想了解RequestFacade中都提供了哪些方法,我们可以直接查看JavaEE的API文档中关于ServletRequest和HttpServletRequest的接口文档,因为RequestFacade实现了其接口就需要重写接口中的方法

Request获取请求数据

HTTP请求数据总共分为三部分内容,分别是请求行,请求头,请求体

获取请求行数据

Snipaste_2024-05-02_15-42-54.png


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //1.获取请求方式: GET   String getMethod()
    System.out.println(request.getMethod());
    //2.获取虚拟目录(项目访问路径):  String getContextPath()  就是我们在tomcat配置的位置设置的路径,是虚拟的,就是随便定义
    //如果设置虚拟路径位置是/那么该方法获取的内容是空字符串
    System.out.println(request.getContextPath());//""
    //3.获取URL(统一资源定位符): http://localhost:8080/request-demo/req1
    //StringBuffer getRequestURL() 获取的是请求资源的绝对路径(含三要素)
    //StringBuilder 和  StringBuffer都表示字符串缓冲区,字符可以改变 。StringBuilder多线程不安全 效率高
    //StringBuffer多线程安全 效率低
    StringBuffer sb = request.getRequestURL();
    String s = sb.toString();
    //  http://localhost:8080/day16/requestRowDemo01Servlet
    System.out.println("s = " + s);
    //4.获取URI(统一资源标识符): /request-demo/req1
    //String getRequestURI() 获取的是请求资源的绝对路径(不含三要素)
    //  /day16/requestRowDemo01Servlet
    System.out.println(request.getRequestURI());
    //5.获取请求参数(GET方式): username=zhangsan&password=123  了解
    //String getQueryString()
    System.out.println(request.getQueryString());//"username=suoge&pwd=1234"
}


获取请求头数据

请求头的数据,格式为key:value
Snipaste_2024-05-02_16-01-18.png
所以可以根据请求头名称获取对应值的方法:
Snipaste_2024-05-02_16-01-48.png

获取请求体数据

浏览器在发送get请求的时候是没有请求体的,所以需要把请求方式变更为post
Snipaste_2024-05-03_10-03-20.png
获取请求体数据的方法:
1)ServletInputStream getInputStream()该方法可以获取字节和字符数据
2)BufferedReader getReader() 获取字符数据
:BufferedReader流是通过request对象来获取的,当请求完成后request对象就会被销毁,request对象被销毁后,BufferedReader流就会自动关闭,所以此处就不需要手动关闭流了。

获取请求参数(通用方式)

  1. 就是在获取之前获取请求方式,然后判断get还是post
  2. 通用方式,不需要判断请求方式(建议)

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/req4" method="get">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1"> 游泳
    <input type="checkbox" name="hobby" value="2"> 爬山 <br>
    <input type="submit">

</form>
</body>
</html>

java代码:

package com.example.resquest;

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.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.function.BiConsumer;

@WebServlet("/req4")
public class RequestDemo4Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        /*
            获取请求参数的通用方式:
                1.Map<String,String[]> getParameterMap() 获取所有的请求参数。
                    抓包冒号左边的作为map集合的key,冒号右边的值作为map集合的value
               2.String[] getParameterValues(String name) 获取指定的值。参数是抓包冒号左边的标识。获取的值放到数组中
               3.String getParameter(String name)获取指定的值。 参数是抓包冒号左边的标识
                    注意:如果参数的name有多个值谁在前面先获取谁

                    抓包结果:
                        username: zhangsan
                        password: 1234
                        hobby: 1
                        hobby: 2
         */

        //获取所有的请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        //遍历所有的请求参数
        parameterMap.forEach((key,value)-> System.out.println(key+"---"+Arrays.toString(value)));

        //获取hobby的值
        String[] hobbies = request.getParameterValues("hobby");
        System.out.println("hobby:"+Arrays.toString(hobbies));

        //获取username的值
        String username = request.getParameter("username");
        System.out.println(username);
    }
}

jdk8遍历map集合

          map.forEach(new BiConsumer<String, String[]>() {
          @Override
          public void accept(String s, String[] strings) {
          }
      });
            BiConsumer中accept为抽象方法,就有一个,所以未函数式接口,能用lambda表达式简写

解决post请求乱码问题

解决思路

  1. 从tomact8开始以后,对于get请求乱码,tomact已经解决。对于post请求中文乱码没有解决,需要我们字节处理
  2. post请求乱码产生的原因和解决思路

Snipaste_2024-05-03_11-37-07.png
说明

  1. 页面使用的编码表是UTF-8编码,tomact使用的默认编码表ISO-8859-1进行解码,编码和解码使用的编码表不一样导致乱码
  2. 解决思路:先按照ISO-8859-1编码,再按照UTF-8进行重新解码

解决方案

方案一

 使用URLEncoder类进行编码:static String encode(String s, String enc)
                          参数:
                              s:编码的字符串
                              enc:使用编码表
 使用URLDecoder进行解码:static String decode(String s, String enc)
                          参数:
                              s:解码的字符串
                              enc:使用编码表

方案二

 使用String类中的方法进行编码:    byte[] getBytes(String charsetName)
                            参数表示指定的编码表,返回值表示编码后的字节数组
 使用String类中的构造方法进行解码:String(byte[] bytes, String charsetName)
                            参数:
                               bytes:字节数组
                               charsetName:表示指定的编码表
                              返回值:解码后的字符串

方案三

          如果是get请求,tomcat8底层已经帮助我们解决完了,我们只需要解决post乱码即可,但是上述
          两种方式对于post请求可以解决乱码,对于get请求本身获取到的已经是正确的数据,处理
          后又乱码了。
          我们的想法是:get请求不用我们自己书写代码处理乱码,只需要我们书写代码处理post乱码。
          我们接下来学习第三种解决方案:
          只解决来自于请求体数据的乱码。而get请求体没有数据,post请求体含有数据,所以我们可以理解为第三种处理方案只				
          是用来解决post乱码的。使用的api是ServletRequest接口中的:
              void setCharacterEncoding(String env)
                  参数:指定的编码表
          注意:该方式的代码必须书写在获取请求数据之前

Request请求转发(前后端分离后使用较少,面试考)

概述

一种在服务器内部的资源跳转方式
Snipaste_2024-05-03_13-13-17.png

  1. 浏览器发送请求给服务器,服务器中对应的资源A接受到请求
  2. 资源A处理完请求后将请求发给资源B
  3. 资源B处理完后将结果响应给浏览器
  4. 请求从资源A到资源B的过程就叫请求转发

实现方式

req.getRequestDispatcher(“资源B路径”).forward(req,resp);
说明:
1)获取这转发器:RequestDispatcher dispatcher = req.getRequestDispatcher(“资源B路径”);
2)转发:RequestDispatcher表示转发器,该接口中有一个方法:forward(request,response)

请求转发资源间共享数据:使用request域对象

  • 存储数据到request域[范围,数据是存储在request对象]中

void setAttribute(String name,Object o);

  • 根据key获取值

Object getAttribute(String name);

  • 根据key删除改键值对

void removeAttribute(String name);

请求转发特点

  1. 地址栏不会发生改变
  2. 可以共享request域对象数据
  3. 一次请求一次响应
  4. 属于服务器内部跳转行为

Request的生命周期

  1. 何时创建?

浏览器第一次访问tomcat服务器的时候

  1. 谁创建

tomact

  1. 创建对象做什么

浏览器第一次访问tomcat服务器的时候,tomcat创建request对象和response对象,传递给servlet中的service方法,然后我们可以在servlet中使用request对象调用方法获取请求数据(请求行 头 体),然后处理业务逻辑,处理完毕,然后tomcat将响应数据给浏览器,浏览器接收到响应之后,tomcat立刻销毁request和response对象。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【20-时间序列预测:使用Scikit-learn处理时间数据】

文章目录 前言理解时间序列数据处理时间数据数据格式与解析时间组件提取时间序列可视化构建时间序列预测模型数据集分割特征工程选择模型验证与评估评价指标选择结论前言 时间序列预测在金融、天气预报和销售分析等领域中扮演着重要角色。在本文中,我们将探讨如何使用Scikit-l…

Linux快速安装Nginx和重新添加模块

目录 一、Nginx快速安装1、下载Nginx2、配置Nginx模块 二、Ngnix重新编译和安装模块 一、Nginx快速安装 1、下载Nginx 直接进入Nginx官网下载Linux最新稳定版本&#xff0c;我之前下载的版本是1.23.0。 2、配置Nginx模块 下载完后我把源码压缩文件解压放在/opt/appl/nginx…

ICode国际青少年编程竞赛- Python-1级训练场-for循环入门

ICode国际青少年编程竞赛- Python-1级训练场-for循环入门 1、 for i in range(4):Dev.step(4)Dev.turnLeft()2、 for i in range(3):Dev.step(6)Dev.turnRight()3、 for i in range(3):Dev.turnRight()Dev.step(2)Dev.turnLeft()Dev.step(-3)4、 for i in range(4):Dev…

DNS、ICMP、NAT以及代理服务器

目录 1. DNS 1.1. DNS 背景 1.2. 域名简介 1.3. 域名解析过程 2. ICMP 2.1. ICMP 的功能 2.2. ICMP 的报文格式 2.3. ping 命令 2.4. traceroute 命令 3. NAT和代理服务器 3.1. NAT 技术 3.2. NAT IP转换过程 3.3. NAT 技术的缺陷 3.4. 代理服务器 3.4.1. 正向…

【redis】Redis数据类型(四)Set类型

目录 Set类型介绍使用场景 Set类型数据结构set的单个元素的添加过程IntSet哈希表内存结构 常用命令SADD示例 SREM示例 SMEMBERS示例 SISMEMBER示例 SCARD示例 SMOVE示例 SPOP示例 SRANDMEMBER示例 SINTER示例 SINTERSTORE示例 SUNION示例 SUNIONSTORE示例 SDIFF示例 SDIFFSTORE…

【每日算法】理论:大模型相关 刷题:队列的应用

上期文章 【每日算法】理论&#xff1a;多模态系列 刷题&#xff1a;栈的应用 文章目录 上期文章一、上期问题二、本期理论问题1、GPT1&#xff0c;2&#xff0c;3的区别2、解决过拟合的方法3、LLM的生成原理4、对比LSTM,GRU,transformer5、zero-shot6、pre-norm和post-norm的…

vscode远程免密ssh原理与实操方法

什么是SSH SSH是一种加密协议&#xff0c;全称为Secure Shell&#xff0c;用于安全地远程登录到服务器或其他远程设备上执行命令或传输文件。它提供了一种安全的加密通信机制&#xff0c;使得远程登录和文件传输等操作不会被恶意攻击者窃取或篡改&#xff0c;确保了数据的保密…

扩展学习|本体研究进展

文献来源&#xff1a; 王向前,张宝隆,李慧宗.本体研究综述[J].情报杂志,2016,35(06):163-170. 一、本体的定义 本体概念被引入人工智能、知识工程等领域后被赋予了新的含义。然而不同的专家学者对本体的理解不同,所给出的定义也有所差异。 人工智能领域的学者Neches(1991)等人对…

eSIM Network搭建指南

有任何关于GSMA\IOT\eSIM\RSP\业务应用场景相关的问题&#xff0c;欢迎W: xiangcunge59 一起讨论, 共同进步 (加的时候请注明: 来自CSDN-iot).

doxygen 辅助阅读代码的神器

简介 Doxygen是一个文档生成工具&#xff0c;主要用于编写编程语言的软件文档。它最初是为C设计的&#xff0c;但后来增加了对C、C#、Java、Objective-C、Python、IDL&#xff08;在某些情况下还有PHP、C#和D&#xff09;的支持。Doxygen可以从一组带有文档注释的源代码文件中…

【数据结构】如何创建一棵红黑树(附动图讲解)

一、前言 二、红黑树的概念 三、红黑树的性质 四、红黑树节点的定义 五、红黑树的插入 5.1 节点的初始颜色 5.2 红黑树的调整 六、红黑树的验证 6.1 验证有序 6.2 验证红黑树性质 七、红黑树与AVL树的比较 一、前言 在前面AVL树的学习中&#xff0c;我们知道了如何…

golang 基础知识细节回顾

之前学习golang的速度过于快&#xff0c;部分内容有点囫囵吞枣的感觉&#xff0c;写gorm过程中有很多违反我常识的地方&#xff0c;我通过复习去修正了我之前认知错误和遗漏的地方。 itoa itoa自增的作用在编辑error code时候作用很大&#xff0c;之前编辑springboot的error c…

【Linux学习】(2)OS的简单了解|Linux的基本指令操作

前言 本文将先简单了解什么是操作系统&#xff0c;再讲解一些Linux的基本指令。 一、操作系统的简单了解 1、什么是操作系统&#xff08;Operating System&#xff0c;简称OS&#xff09;&#xff1f; OS是一款做软硬件管理的软件。软硬件的体系结构图&#xff1a; 硬件&…

探索高级聚类技术:使用LLM进行客户细分

在数据科学领域&#xff0c;客户细分是理解和分析客户群体的重要步骤。最近&#xff0c;我发现了一个名为“Clustering with LLM”的GitHub仓库&#xff0c;它由Damian Gil Gonzalez创建&#xff0c;专门针对这一领域提供了一些先进的聚类技术。在这篇文章中&#xff0c;我将概…

「 网络安全常用术语解读 」SBOM主流格式SWID详解

国际标准化组织&#xff08;ISO&#xff09;和国际电工委员会&#xff08;International Electrotechnical Commission&#xff0c;IEC&#xff09;发布了ISO/IEC 19770-2软件标识&#xff08;Software Identification&#xff0c;SWID&#xff09;标签标准&#xff0c;该标准定…

Qt模型视图代理之MVD(模型-视图-代理)概念的简单介绍

往期回顾 Qt绘图与图形视图之Graphics View坐标系的简单介绍-CSDN博客 Qt绘图与图形视图之基本图元绘制的简单介绍-CSDN博客 Qt绘图与图形视图之自定义图元实现拖拽、拉伸、旋转功能-CSDN博客 Qt模型视图代理之MVD(模型-视图-代理)概念的简单介绍 一、基本概念 Qt模型视图代理…

前端页面平滑过渡解决方案

一、问题产生 在使用图片作为页面背景时&#xff0c;无法使用transtion进行平滑过渡&#xff0c;直接切换背景又会降低使用体验。 二、解决方式 使用clip-path对背景图片裁剪配合transtion实现平滑过渡的效果 三、效果展示 网址&#xff1a;ljynet.com 四、实现方式 tem…

ICode国际青少年编程竞赛- Python-1级训练场-for循环练习

ICode国际青少年编程竞赛- Python-1级训练场-for循环练习 1、 for i in range(3):Dev.step(4)Dev.turnLeft()2、 for i in range(3):Dev.step(2)Dev.turnRight()Dev.step(2)Dev.turnLeft()3、 for i in range(3):Dev.step(2)Dev.turnRight()Dev.step(2)Dev.turnLeft()4、 for…

32.Docker认识

Docker介绍 Docker是一个快速交付应用&#xff0c;运行应用的技术。 1.可以将程序、依赖、运行环境一起打包为一个镜像&#xff0c;可以迁移到任意Linux操作系统。 2.运行时利用沙箱机制行程隔离容器&#xff0c;各个应用互不干扰。 3.启动、移除都可以通过一行命令完成&am…

算法学习系列(五十五):背包模型(三)

目录 引言一、潜水员二、背包问题求具体方案三、机器分配四、开心的今明五、金明的预算方案 引言 今天介绍的是背包模型&#xff0c;还是以题目的形式来介绍的。主要讲了背包问题求方案&#xff0c;就是由最优方案递推回去即可。还有就是一些比较经典的背包问题&#xff0c;其…