图解HTTP请求Tomcat服务器实现前后端交互-1

简介: 图解HTTP请求Tomcat服务器实现前后端交互

前言

很多同学在学习到Servlet的时候,需要通过Tomcat去接收HTTP的响应以实现这个前后端交互的场景,因此理解起来就比较困难,之前在写Java代码的时候,我们只是在一个程序里面通过方法1调用方法2以达成基本的代码逻辑。不过现在呢,我们是去进行一个前后端的交互,本质实现的是两个程序之间的相互通信

  • 这就需要去理解一个接口的思想,后端Servlet通过注解的形式去为前端提供一个访问的接口,前端只需要通过这个找到对应的服务器接口,Tomcat服务器就会将HTTP请求解析为request对象,以此很好地在内部通过Servlet来处理这个对象,再构造出response对象由返回给Tomcat,最后由Tomcat继续解析为HTTP响应返回给浏览器

还是有点不同的同学可以看看下面这个动图,解释得很好,出自JavaWeb——Servlet

如何构造HTTP请求?

当然,前端在给后端发送HTTP请求之前,它要先构造出这个请求才行,下面我介绍三种构造HTTP请求的方式

1、通过form表单构造HTTP请求

① form发送GET请求

  • 那首先我们要去写一个表单
  • 【action】属性为https://www.sogou.com/,也就是指定表单要提交到的地址处(URL),这里是交给搜狗的服务器来处理我们所提交的表单内容
  • 【method】属性为get,表示在提交表单时所需要用到的HTTP方法,这里的话是使用get(默认),不过对于表单来说我们用的都是post,下一小节会介绍
  • 写好form表单的属性后,里面就是供用户操作的一些控件,分别为两个输入框和一个提交按钮,可以看到两个输入文本框我不仅设置了必要的【type】属性,而且还分别设置了【name】属性,为的就是实现的header(请求头)中所呈现==键值对==
<form action="https://www.sogou.com/" method="get">
    <input type="text" name="UserId">
    <input type="text" name="ClassId">
    <!-- 点击这个按钮会触发form表单的提交操作,也就是构造HTTP请求发给服务器 -->
    <input type="submit" value="提交">
</form>

image.png

  • 可以看到,当我点击提交的时候,就来到了搜狗的主页

image.png

  • 接着我们通过Fiddler抓包工具就可以去查看这个HTTP请求,对于GET请求来说,我们主要看这个第一行就可以了

image.png==下面是我们对form表单的设置与HTTP请求报文发生的对应变化==image.png

② form发送POST请求

  • 当然,form表单除了向服务器发送GET请求外,还可以发送POST请求,只需要修改一下这个【method】属性即可
<form action="https://www.sogou.com/" method="post">
    <input type="text" name="UserId">
    <input type="text" name="ClassId">
    <!-- 点击这个按钮会触发form表单的提交操作,也就是构造HTTP请求发给服务器 -->
    <input type="submit" value="提交">
</form>
  • 然后我们看到form表单所发送过来的HTTP请求的原生文件,可以观察到与GET请求相比,里面的内容出现了差距

image.png

  • 然后我们来分析一下这个报文格式的变化,可以看到对于form构造的post请求来说,body里面的数据格式就和query string是非常相似的,也是【键值对结构
  • 键值对之间用 & 来分割
  • 键和值之间用 = 来分割

image.png

2、通过Ajax构造HTTP请求

当然,除了form表单之外,我们还有一种功能更强的构造HTTP请求的方式,那就是通过ajax来实现

同步等待与异步等待的感性理解

【概念】:ajax 全称 Asynchronous Javascript And XML, 是 2005 年提出的一种 JavaScript 给服务器发送HTTP 请求的方式.

  • 其最大的特点就是:可以不需要刷新页面/页面跳转 就能进行数据传输.
  • 其实ajax最需要关注的点就是Asynchronous ,也就是【异步】的意思,【同步】相信学习过多线程的同学都有听说过,使用关键字synchronized就可以去实现了,那我们就要来谈谈这个【同步】和【异步】的区别了

我在这里举一个形象点的例子

  • 比如说你现在和你和女朋友在谈恋爱,你呢想约她出去玩,于是来到她的宿舍楼下,打电话问她什么时候出来,此时她说:“等一下”,但是呢一般女生说的等一下通常不是三五分钟,起码是半个小时起步⏰于是呢你就开始了漫长的等待~~
  • 如果你只是戴戴地望着宿舍大门等她出来,等到她露头就马上迎上去,此时就叫做【同步的等待】
  • 如果你觉得这么等着比较无聊,然后来到了宿舍楼下周围的树荫下打开了你心爱的《Java编程思想》,那么此时你也是在等待,不过这叫做【异步的等待】

image.png

相信通过上述这个案例你一定理解了什么是【同步等待】和【异步等待】了

==A 等待 B==

👉 A始终盯着B,A负责关注B啥时候就绪👉 A不盯着B,B就绪之后主动通知A

  • HTML中,通过ajax 发起http请求,就属于是 “异步” 方式,现在我们就来说说如何使用ajax去发起http请求
  • 不过呢在实现ajax前我们要先引入一个外部的jQuery,它是一种流行的 JavaScript 库,通过封装常见任务和跨浏览器兼容性问题来使 JavaScript 更易于使用
  • 首先进入bootcdn的官网,把这段链接复制下来即可,然后将其粘贴到<script>的src属性中,表示引入一个外部的js文件

image.png

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
  • 接下去我们就可以去构造ajax请求了,需要构造的内容其实和form表单类似,只是属性有所不同罢了
  • 在form表单中我们所写的method,这里变成了type
  • 在form表单中我们所写的action,这里变成了url
  • 其实它们本质还是相同的,只是换了个说法而已。然后接下去呢就可以看到有一个success属性,它的内部似乎是一个function函数。这里要重点说一下,它就是我们在C语言中所学习的回调函数,这个底层的逻辑是类似的,当我们通过ajax构造的HTTP请求到达服务器后,服务器再进行处理将其返回给浏览器,此时浏览器就会触发该回调函数,去进行执行相应的代码
  • 上述的这个回调逻辑其实就体现了【异步】的思想,ajax不需要等待浏览器给它响应,就可以先把自己的代码先跑完,所以我们可以预期一下console控制台中的第一句便是这个【浏览器立即往下执行后续代码
<script>
    $.ajax({
        type: 'get',
        url: "https://www.sogou.com/",
        // 此处的success就声明了一个回调函数,就会在服务器响应,回到浏览器的时候触发该回调
        // 正是此处的回调体现了 “异步”
        success: function(data){
            console.log("当服务器返回的响应到达浏览器后,浏览器触发该回调,通知到咱们的代码中");
        }
    })
    console.log("浏览器立即往下执行后续代码");
</script>
  • 通过去console控制台进行观察我们可以发现打印出来的结果是【浏览器立即往下执行后续代码】,这就意味着它是在回调函数之前执行的,但回调函数没有执行只是因为搜狗那里的服务器并没有处理我们呢发送过去的HTTP请求,所以便报出了异常,后面我们自己通过Tomcat去模拟服务器调用Servlet来进行处理即可

image.png【小结一下】:

  • 和form相比,ajax功能更强
  1. 支持put、delete等方法
  2. ajax发送的请求可以灵活设置header
  3. ajax发送的请求body也可以灵活设置

3、使用postman构造HTTP请求

对于postman而言,它是专门用来进行http请求测试的工具,如有不懂可以看看这篇文章链接

  • 有关如何去构造HTTP请求,我下面做一个演示,很简单,只需要点点鼠标即可🖱
  • 此时搜狗那边就可以收到我们的HTTP请求了,但是人家不给出回应也没办法查看,下面我们自己去实现前后端交互的时候我会继续做演示

4、通过 Java socket 构造 HTTP 请求

上面三种是我们在平常工作中用得最多的,还有一种就是通过 Java socket 来进行构造,可以了解一下~

public class HttpClient {
    private Socket socket;
    private String ip;
    private int port;
    public HttpClient(String ip, int port) throws IOException {
        this.ip = ip;
        this.port = port;
        socket = new Socket(ip, port);
   }
    public String get(String url) throws IOException {
        StringBuilder request = new StringBuilder();
        // 构造首行
        request.append("GET " + url + " HTTP/1.1\n");
        // 构造 header
        request.append("Host: " + ip + ":" + port + "\n");
        // 构造 空行
        request.append("\n");
        // 发送数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(request.toString().getBytes());
        // 读取响应数据
        InputStream inputStream = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int n = inputStream.read(buffer);
        return new String(buffer, 0, n, "utf-8");
   }
    public String post(String url, String body) throws IOException {
        StringBuilder request = new StringBuilder();
        // 构造首行
        request.append("POST " + url + " HTTP/1.1\n");
        // 构造 header
        request.append("Host: " + ip + ":" + port + "\n");
        request.append("Content-Length: " + body.getBytes().length + "\n");
        request.append("Content-Type: text/plain\n");
        // 构造 空行
        request.append("\n");
        // 构造 body
        request.append(body);
        // 发送数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(request.toString().getBytes());
        // 读取响应数据
        InputStream inputStream = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int n = inputStream.read(buffer);
        return new String(buffer, 0, n, "utf-8");
   }
    public static void main(String[] args) throws IOException {
        HttpClient httpClient = new HttpClient("42.192.83.143", 8080);
        String getResp = httpClient.get("/AjaxMockServer/info");
        System.out.println(getResp);
        String postResp = httpClient.post("/AjaxMockServer/info", "this is 
body");
        System.out.println(postResp);
   }
}
相关文章
|
监控 Java 应用服务中间件
低并发编程|如何用720个请求让后端服务器瘫痪
本次故障因应用启动时未有效校验核心依赖模块初始化异常,导致后续请求处理中抛出无法捕获的错误,引发线程阻塞,最终耗尽HSF线程池,服务不可用。排查发现类初始化失败且异常未被正确处理,结合线程无限等待问题,确认为依赖初始化异常与流处理中断所致。修复措施包括加强启动校验、捕获Throwable及设置合理超时。总结指出,系统稳定性需从细节入手,防微杜渐,避免连锁故障。
低并发编程|如何用720个请求让后端服务器瘫痪
|
Python
使用Python实现multipart/form-data文件接收的http服务器
至此,使用Python实现一个可以接收 'multipart/form-data' 文件的HTTP服务器的步骤就讲解完毕了。希望通过我的讲解,你可以更好地理解其中的逻辑,另外,你也可以尝试在实际项目中运用这方面的知识。
756 69
|
C# 图形学 开发者
Unity开发中使用UnityWebRequest从HTTP服务器下载资源。
总之,UnityWebRequest就是游戏开发者手中的万能钓鱼竿,既可以获取文本数据,也能钓上图片资源,甚至是那声音的涟漪。使用UnityWebRequest的时候,你需要精心准备,比如确定URL、配置请求类型和头信息;发起请求;巧妙处理钓获的数据;还需要机智面对网络波澜,处理各种可能出现的错误。按照这样的过程,数据的钓取将会是一次既轻松愉快也效率高效的编程钓鱼之旅。
819 18
|
应用服务中间件 网络安全 数据安全/隐私保护
网关服务器配置指南:实现自动DHCP地址分配、HTTP服务和SSH无密码登录。
哇哈哈,道具都准备好了,咱们的魔术秀就要开始了。现在,你的网关服务器已经魔法满满,自动分配IP,提供网页服务,SSH登录如入无人之境。而整个世界,只会知道效果,不会知道是你在幕后操控一切。这就是真正的数字世界魔法师,随手拈来,手到擒来。
647 14
|
JSON API 数据安全/隐私保护
使用curl命令在服务器上执行HTTP请求
总的来说,curl是一个非常强大的工具,它可以让你在命令行中发送各种类型的HTTP请求。通过学习和实践,你可以掌握这个工具,使你的工作更加高效。
1422 30
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
存储 数据库 Python
使用HTTP POST协议将本地压缩数据发送到服务器
总的来说,使用HTTP POST协议将本地压缩数据发送到服务器是一个涉及多个步骤的过程,包括创建压缩文件,设置HTTP客户端,发送POST请求,以及服务器端的处理。虽然这个过程可能看起来复杂,但一旦你理解了每个步骤,就会变得相对简单。
495 19
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
777 0
|
存储 安全 数据安全/隐私保护
HFS-快速创建HTTP服务器
鉴于HFS的操作简便和方便快捷,它在满足快速,临时的文件分享和传输需求上,能够发挥出巨大的作用。只要明确了以上的安全警告,并做好了必需的安全设置,HFS将是一款实用的HTTP服务器工具。
1723 9
|
安全 网络安全 定位技术
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
457 22