图解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);
   }
}
相关文章
|
12天前
|
缓存 应用服务中间件 Apache
HTTP 范围Range请求
HTTP范围请求是一种强大的技术,允许客户端请求资源的部分内容,提高了传输效率和用户体验。通过正确配置服务器和实现范围请求,可以在视频流、断点续传下载等场景中发挥重要作用。希望本文提供的详细介绍和示例代码能帮助您更好地理解和应用这一技术。
57 19
|
1月前
|
JSON Java 数据格式
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
89 25
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
|
20天前
|
JSON JavaScript 前端开发
什么是HTTP POST请求?初学者指南与示范
HTTP POST请求是一种常用的HTTP方法,主要用于向服务器发送数据。通过合理设置请求头和请求主体,可以实现数据的可靠传输。无论是在客户端使用JavaScript,还是在服务器端使用Node.js,理解和掌握POST请求的工作原理和应用场景,对于Web开发至关重要。
185 18
|
20天前
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
62 2
|
25天前
|
缓存 负载均衡 监控
HTTP代理服务器在网络安全中的重要性
随着科技和互联网的发展,HTTP代理IP中的代理服务器在企业业务中扮演重要角色。其主要作用包括:保护用户信息、访问控制、缓存内容、负载均衡、日志记录和协议转换,从而在网络管理、性能优化和安全性方面发挥关键作用。
60 2
|
1月前
|
Web App开发 大数据 应用服务中间件
什么是 HTTP Range请求(范围请求)
HTTP Range 请求是一种非常有用的 HTTP 功能,允许客户端请求资源的特定部分,从而提高传输效率和用户体验。通过合理使用 Range 请求,可以实现断点续传、视频流播放和按需加载等功能。了解并掌握 HTTP Range 请求的工作原理和应用场景,对开发高效的网络应用至关重要。
123 15
|
1月前
|
数据采集 JSON 测试技术
Grequests,非常 Nice 的 Python 异步 HTTP 请求神器
在Python开发中,处理HTTP请求至关重要。`grequests`库基于`requests`,支持异步请求,通过`gevent`实现并发,提高性能。本文介绍了`grequests`的安装、基本与高级功能,如GET/POST请求、并发控制等,并探讨其在实际项目中的应用。
54 3
|
1月前
|
Web App开发 网络安全 数据安全/隐私保护
Lua中实现HTTP请求的User-Agent自定义
Lua中实现HTTP请求的User-Agent自定义
|
4月前
|
监控 安全 搜索推荐
设置 HTTPS 协议以确保数据传输的安全性
设置 HTTPS 协议以确保数据传输的安全性
|
21天前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
84 1