图解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);
   }
}
相关文章
|
19天前
|
Java
java原生发送http请求
java原生发送http请求
|
26天前
|
网络协议 Linux iOS开发
推荐:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求
推荐:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求
56 1
|
8天前
|
安全 Java 网络安全
Servlet 教程 之 Servlet 客户端 HTTP 请求 2
Servlet教程介绍了如何在Servlet中处理HTTP请求,包括获取Cookie、头信息、参数、Session等。方法如:`getCookies()`、`getAttributeNames()`、`getHeaderNames()`、`getParameterNames()`等。还能获取身份验证类型、字符编码、MIME类型、请求方法、远程用户信息、URL路径、安全通道状态以及请求内容长度等。此外,可通过`getSession()`创建或获取Session,并以`Map`形式获取参数。
21 8
|
7天前
|
XML Java 数据格式
Servlet 教程 之 Servlet 服务器 HTTP 响应 3
`Servlet`教程示例展示了如何创建一个HTTP响应,使用`@WebServlet(&quot;/Refresh&quot;)`的`Refresh`类继承`HttpServlet`。在`doGet`方法中,设置了`Refresh`头以每5秒自动刷新,并用`setContentType(&quot;text/html;charset=UTF-8&quot;)`设定内容类型。还使用`Calendar`和`SimpleDateFormat`获取并格式化当前时间显示。相应的`web.xml`配置指定了Servlet路径。当访问此Servlet时,页面将每5秒更新一次显示的系统时间。
17 4
|
1天前
|
Go 开发者
Golang深入浅出之-HTTP客户端编程:使用net/http包发起请求
【4月更文挑战第24天】Go语言的`net/http`包在HTTP客户端编程中扮演重要角色,但使用时需注意几个常见问题:1) 检查HTTP状态码以确保请求成功;2) 记得关闭响应体以防止资源泄漏;3) 设置超时限制,避免长时间等待;4) 根据需求处理重定向。理解这些细节能提升HTTP客户端编程的效率和质量。
11 1
|
2天前
|
存储 缓存 开发框架
Flutter的网络请求:使用Dart进行HTTP请求的技术详解
【4月更文挑战第26天】了解Flutter网络请求,本文详述使用Dart进行HTTP请求
|
3天前
|
JSON 数据格式 索引
ES 查看索引的属性的http请求
在 Elasticsearch 中,要查看索引的属性,可以通过发送 HTTP 请求来执行以下操作: 1. **获取索引的映射(Mapping)**: 可以使用 `GET` 请求访问 Elasticsearch 的 `_mapping` 端点来获取特定索引的映射信息。 示例请求: ```http GET http://<elasticsearch_host>:<port>/<index_name>/_mapping ``` 2. **获取索引的设置(Settings)**: 可以使用 `GET` 请求访问 Elasticsearch 的 `_setting
|
4天前
|
JSON JavaScript 前端开发
服务器通信:使用WebSocket与后端实时交互
【4月更文挑战第24天】WebSocket为解决服务器与客户端实时双向通信问题而生,常用于聊天、游戏和实时通知等场景。本文通过4步教你实现WebSocket通信:1) 客户端使用JavaScript创建WebSocket连接;2) 监听`open`、`message`和`close`事件;3) 使用`send`方法发送数据;4) 使用`close`方法关闭连接。服务器端则需处理连接和数据发送,具体实现依后端技术而定。WebSocket为现代Web应用的实时交互提供了强大支持。
|
4天前
|
JSON 测试技术 API
Python的Api自动化测试使用HTTP客户端库发送请求
【4月更文挑战第18天】在Python中进行HTTP请求和API自动化测试有多个库可选:1) `requests`是最流行的选择,支持多种请求方法和内置JSON解析;2) `http.client`是标准库的一部分,适合需要低级别控制的用户;3) `urllib`提供URL操作,适用于复杂请求;4) `httpx`拥有类似`requests`的API,提供现代特性和异步支持。根据具体需求选择,如多数情况`requests`已足够。
9 3
|
9天前
|
小程序 开发者
体验版小程序为何无法访问云端服务器后端接口(请求失败...(已完美解决附加图片))?
体验版小程序为何无法访问云端服务器后端接口(请求失败...(已完美解决附加图片))?
14 0