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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 图解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

相关文章
|
25天前
|
缓存 负载均衡 监控
HTTP代理服务器在网络安全中的重要性
随着科技和互联网的发展,HTTP代理IP中的代理服务器在企业业务中扮演重要角色。其主要作用包括:保护用户信息、访问控制、缓存内容、负载均衡、日志记录和协议转换,从而在网络管理、性能优化和安全性方面发挥关键作用。
60 2
|
2月前
|
XML 前端开发 JavaScript
PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑
本文深入探讨了PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑;Ajax则通过异步请求实现页面无刷新更新。文中详细介绍了两者的工作原理、数据传输格式选择、具体实现方法及实际应用案例,如实时数据更新、表单验证与提交、动态加载内容等。同时,针对跨域问题、数据安全与性能优化提出了建议。总结指出,PHP与Ajax的结合能显著提升Web应用的效率和用户体验。
63 3
|
2月前
|
安全 API 网络安全
使用OkHttp进行HTTPS请求的Kotlin实现
使用OkHttp进行HTTPS请求的Kotlin实现
|
3月前
|
JSON JavaScript 前端开发
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
76 22
|
3月前
使用Netty实现文件传输的HTTP服务器和客户端
本文通过详细的代码示例,展示了如何使用Netty框架实现一个文件传输的HTTP服务器和客户端,包括服务端的文件处理和客户端的文件请求与接收。
97 1
使用Netty实现文件传输的HTTP服务器和客户端
|
3月前
|
前端开发 JavaScript Java
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
104 4
|
4月前
|
监控 网络协议 应用服务中间件
【Tomcat源码分析】从零开始理解 HTTP 请求处理 (第一篇)
本文详细解析了Tomcat架构中复杂的`Connector`组件。作为客户端与服务器间沟通的桥梁,`Connector`负责接收请求、封装为`Request`和`Response`对象,并传递给`Container`处理。文章通过四个关键问题逐步剖析了`Connector`的工作原理,并深入探讨了其构造方法、`init()`与`start()`方法。通过分析`ProtocolHandler`、`Endpoint`等核心组件,揭示了`Connector`初始化及启动的全过程。本文适合希望深入了解Tomcat内部机制的读者。欢迎关注并点赞,持续更新中。如有问题,可搜索【码上遇见你】交流。
【Tomcat源码分析】从零开始理解 HTTP 请求处理 (第一篇)
|
2月前
|
存储 Oracle 关系型数据库
oracle服务器存储过程中调用http
通过配置权限、创建和调用存储过程,您可以在Oracle数据库中使用UTL_HTTP包发起HTTP请求。这使得Oracle存储过程可以与外部HTTP服务进行交互,从而实现更复杂的数据处理和集成。在实际应用中,根据具体需求调整请求类型和错误处理逻辑,以确保系统的稳定性和可靠性。
101 0
|
3月前
|
前端开发 Java
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
文章介绍了如何使用SpringBoot创建简单的后端服务器来处理HTTP请求,包括建立连接、编写Controller处理请求,并返回响应给前端或网址。
65 0
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
|
3月前
|
安全 网络安全 数据安全/隐私保护
HTTPS 请求中的证书验证详解(Python版)
HTTPS 请求中的证书验证详解(Python版)
252 0