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

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

如何实现前端给后端传参

在学会了如何去自己手动构造HTTP请求后,我们就要去实现服务器去接收这个HTTP请求然后处理它并且处理后的内容返回,此时就需要使用到我们之前说到故的Tomcat + Servlet来实现了

1、query string获取前端发起的GET请求

首先第一种,后端通过query string的方式去获取前段的GET请求,对于query string 我们在讲解HTTP协议的时候有说起过,就是?后面加上键值对的形式去构成

image.png

那现在的话我们就要通过后端的代码来处理这个请求了

  • 首先最重要的就是加要上这个@WebServlet()的注解,这个其实就相当于服务端提供给外部的一个标识,前段便可通过这个注解的标识来发送对应的HTTP请求
  • 当然在Tomcat服务器接收到这个HTTP请求后,还要去将其解析为【HttpServletRequest 】对象,接着便将其交给Servlet做处理,这里我们使用getParameter()就可以通过找寻对应的key来获取相关的value了,最后呢通过resp对象再给到浏览器做响应
@WebServlet("/getParameter")
public class GetParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html charset=utf-8");
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        resp.getWriter().write("userId = " + userId + " classId = " + classId);
    }
}
  • 最后我们就可以看到浏览器上显示出了对应的内容

image.png

2、form表单获取前端发起的POST请求【⭐】

GET请求发送完后,我们再来试试POST请求,主要是通过form表单来实现

  • 这里的HTML代码我们前面在通过form表单构造HTTP请求的时候有写过
<form action="postParameter" method="post">
    <input type="text" name="userId">
    <input type="text" name="classId">
    <input type="submit" value="提交">
</form>

image.png

  • 那后端这块的逻辑还是和query string差不多,就是重写的方法要为doPost()而已,然后的话注解标记记得也做个修改
@WebServlet("/postParameter")
public class PostParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html charset=utf-8");
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        resp.getWriter().write("userId = " + userId + " classId = " + classId);
    }
}
  • 看到最后返回的结果还是这样,通过无论是GET还是POST的请求一样都可以进行处理

image.png

重点:『图解前后端交互全过程』

对于form表单这种请求来说,可能对于一些初学者不是很好理解,这里我画了两种图,希望可以帮助到你

==网页端与服务端交互请求全过程==image.png

==浏览器与tomcat的两次交互过程==image.png

3、json格式解析获取前端发起的POST请求

如果 POST 请求中的 body 是按照 JSON 的格式来传递,那我们在前后端交互的过程中又会发生怎么微妙的变化呢?

① postman发送HTTP请求

  • 首先我们简单一点,使用现有的工具postman去构造一个body为【json】格式的POST请求

image.png

  • 然后再来到后端这里写Servlet的代码逻辑处理这个POST请求。不过呢,这和我们上面缩写的可不太一样。因为在body中是【json】格式的数据,因此我们无法直接通过某种方法来精准获取里面的内容,那就只有一个办法:全部读出来!
  • 那在讲解网络socket的时候,我们有说到过可以用getInputStream()去读取管道中的字节流,倒入到容器中,取多少倒多少,最后再转换为String的对象,打印出来的内容即为我们读取到的对象,代码如下👇
@WebServlet("/postParameterP")
public class PostParameterPostman extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //在流对象中读取的字节数取决于ContentLength
        int length = req.getContentLength();
        byte[] buffer = new byte[length];
        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);       //以字节形式读取HTTP报文格式中的数据
        String body = new String(buffer, 0, length, "utf-8");
        resp.getWriter().write(body);
        System.out.println(body);
    }
}

最后我们来看一下运行结果吧

image.png

② Ajax构造HTTP请求

说完了使用postman来发送HTTP请求,然后我们再用Ajax来试试,前面我们有介绍过了,但是人家搜狗的服务器不处理我们的请求,因此就报出了错误,但现在我们学习了Tomcat和Servlet后,就就可以自己去实现服务端的代码逻辑了

@WebServlet("/postParameterA")
public class PostParameterAjax extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("applicaiton/json;charset=utf-8");
        String body = readBody(req);
        resp.getWriter().write(body);
    }
    private String readBody(HttpServletRequest req) throws IOException {
        //首先获取到body主体的内容长度
        int length = req.getContentLength();
        byte[] body = new byte[length];
        InputStream inputStream = req.getInputStream();
        inputStream.read(body);     //把管道中的数据读入桶中
        return new String(body, 0, length, "utf-8");    //再构造String对象返回
    }
}
  • 对于前端的代码,我们要做一些修改,改用按钮点击事件
<button onclick="sendJson()">发送 Json 格式POST请求</button>
  • JS的话把Ajax的请求包在sendJson()的按钮点击事件中,并且写好对应的5个属性,
<script>
    function sendJson(){
        ajax({
            method: 'POST',
            url: 'postParameterA',
            contentType: 'application/json;charset=uft-8',
            body: JSON.stringify({
                "userId": 10, 
                "classId": 20
            }),
            callback: function(body, status){
                console.log("回调函数会在之后调用");
                console.log(body);
            }
        })
    }
    console.log("浏览器立即往下执行后续代码");
    function ajax(args) {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            // 0: 请求未初始化
            // 1: 服务器连接已建立
            // 2: 请求已接收
            // 3: 请求处理中
            // 4: 请求已完成,且响应已就绪
            if (xhr.readyState == 4) {
                args.callback(xhr.responseText, xhr.status)
            }
        }
        xhr.open(args.method, args.url);
        if (args.contentType) {
            xhr.setRequestHeader('Content-type', args.contentType);
        }
        if (args.body) {
            xhr.send(args.body);
        } else {
            xhr.send();
        }
    }
</script>

接下去我们来看看运行结果

  • 首先是一开始进入浏览器的样子,可以看到就打印出了我们在最后所写这句话,然后并没有去调用这个callback()回调函数,这是因为我们在前端的页面中什么都没有做,即没有向服务器发送HTTP请求,因此也不会触发这个回调函数的调用机制

image.png

  • 不过在我们点击了这个按钮后,网页端便发送了一个POST请求给到服务端这里,服务端在接收并处理这个HTTP报文后,返回给浏览器做响应,此时这个回调函数便被调用了,打印出了语句和【json】格式的body主体

image.png

拓展:Jackson第三方库解析json格式

就上面两种构造json格式的方法,我们在服务器这边只是将整个body给读了出来,但是,但是并没有按照键值对的方式来处理,即无法根据key获取value

  • 在前面的【query string】和【form表单】中,我们可以使用getParameter()这个方法来获取对应的value值,对于【json】格式的数据,我们可以使用第三方库来解决,这个库有很多,例如gson、fastjson,但是在这里我推荐使用 Jackson
  • 为什么推荐这个呢?相信学习过Spring MVC的同学都应该清楚,它里面天然就支持处理json格式的数据,就是因为内置了Jackson这个库来解析json格式

第一步: 在中央仓库中搜索 Jackson, 选择 JackSon Databind

image.png

第二步: 选择2.12.3版本,找到Maven依赖image.pngimage.png第三步: 在pom.xml文件中添加这个Maven依赖

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>

第四步:重新创建一个Java类,继承自HttpServlet类,然后使用Jackson中的核心对象ObjectMapper去完成json格式的解析

class Student{
    public String userId;
    public String classId;
}
@WebServlet("/postParameterJaskson")
public class PostParameterJaskson extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.使用Jackson使用到的核心对象
        ObjectMapper objectMapper = new ObjectMapper();
        // 2.使用里面的readValue()方法把里面具有json格式的数据转换为Java对象
        Student student = objectMapper.readValue(req.getInputStream(), Student.class);
        // 3.显示出解析后的数据
        System.out.println("userId = " + student.userId + " classId = " + student.classId);
        resp.getWriter().write("userId = " + student.userId + " classId = " + student.classId);
    }
}

第五步: 在postman中修改对应的WebServer注解,给对应的接口发送HTTP请求,最后获取到服务器和浏览器都观察到解析后的结果

image.pngimage.png

这里讲解一下最后的这段代码,可能有的同学不太理解

  • JsonData 这个类用来表示解析之后生成的 JSON 对象. 这个类的属性的名字和类型要和 JSON 字符串的 key 相对应.
  • Jackson 库的核心类为 ObjectMapper. 其中的 readValue() 方法把一个 JSON 字符串转成 Java 对象. 其中的 writeValueAsString() 方法把一个 Java 对象转成 JSON 格式字符串.
  • readValue 的第二个参数为 JsonData 的 类对象. 通过这个类对象, 在 readValue 的内部就可以借助【反射机制】来构造出 JsonData 对象, 并且根据 JSON 中key 的名字, 把对应的 value 赋值给 JsonData 的对应字段.
  • 可以来看看这个Jackson库解析【json】格式的全过程,就会很清楚了

image.png

总结与提炼

最后来总结一下本文所介绍的内容:book:

  • 本文的开端,我们首先了解了如何去构造一个HTTP请求,可以通过form表单、Ajax、postman以及Java Socket的去进行构造,我们主要还是掌握前三种,对于form表单而言最为常见,我介绍了GET请求和POST请求两种,不过对于form表单来说一般发送的还是POST请求居多
  • 知道了如何构造HTTP请求,此时前端就可以在HTTP请求中放置一些内容,后端从这个请求中获取到内容然后处理,那这个前后端的交互就需要有一个接口,它就是【Servlet注解】,前端通过这个@WebServlet()里面的参数,决定自己的URL是怎样的;后端呢则通过这个URL来进行精准地接收并做出相应的处理,而且还需根据前端发起的不同请求在不同的方法里做处理(doGet、doPost)
  • 对于这个前后端的交互逻辑,如果还有不理解的同学可以多去画画图,通过postman去发送各种的HTTP请求,然后通过Fidder抓包进行观察,去清楚双方是如何进行一发一收的这么一个交互逻辑

以上就是本文要介绍的所有内容,感谢您的阅读:rose

相关文章
|
27天前
HTTP协议中请求方式GET 与 POST 什么区别 ?
GET和POST的主要区别在于参数传递方式、安全性和应用场景。GET通过URL传递参数,长度受限且安全性较低,适合获取数据;而POST通过请求体传递参数,安全性更高,适合提交数据。
299 2
|
3月前
|
JavaScript 前端开发 API
Node.js中发起HTTP请求的五种方式
以上五种方式,尽管只是冰山一角,但已经足以让编写Node.js HTTP请求的你,在连接世界的舞台上演奏出华丽的乐章。从原生的 `http`到现代的 `fetch`,每种方式都有独特的风格和表现力,让你的代码随着项目的节奏自由地舞动。
397 65
|
2月前
|
Go 定位技术
Golang中设置HTTP请求代理的策略
在实际应用中,可能还需要处理代理服务器的连接稳定性、响应时间、以及错误处理等。因此,建议在使用代理时增加适当的错误重试机制,以确保网络请求的健壮性。此外,由于网络编程涉及的细节较多,彻底测试以确认代理配置符合预期的行为也是十分重要的。
120 8
|
1月前
|
JSON JavaScript API
Python模拟HTTP请求实现APP自动签到
Python模拟HTTP请求实现APP自动签到
|
2月前
|
缓存
|
3月前
|
C# 图形学 开发者
Unity开发中使用UnityWebRequest从HTTP服务器下载资源。
总之,UnityWebRequest就是游戏开发者手中的万能钓鱼竿,既可以获取文本数据,也能钓上图片资源,甚至是那声音的涟漪。使用UnityWebRequest的时候,你需要精心准备,比如确定URL、配置请求类型和头信息;发起请求;巧妙处理钓获的数据;还需要机智面对网络波澜,处理各种可能出现的错误。按照这样的过程,数据的钓取将会是一次既轻松愉快也效率高效的编程钓鱼之旅。
184 18
|
1月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
2月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
3月前
|
应用服务中间件 网络安全 数据安全/隐私保护
网关服务器配置指南:实现自动DHCP地址分配、HTTP服务和SSH无密码登录。
哇哈哈,道具都准备好了,咱们的魔术秀就要开始了。现在,你的网关服务器已经魔法满满,自动分配IP,提供网页服务,SSH登录如入无人之境。而整个世界,只会知道效果,不会知道是你在幕后操控一切。这就是真正的数字世界魔法师,随手拈来,手到擒来。
185 14
|
2月前
|
缓存 JavaScript 前端开发
Vue 3 HTTP请求封装导致响应结果无法在浏览器中获取,尽管实际请求已成功。
通过逐项检查和调试,最终可以定位问题所在,修复后便能正常在浏览器中获取响应结果。
154 0