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

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

相关文章
|
6天前
|
API 数据安全/隐私保护
Haskell中的HTTP请求:代理与响应状态检查
Haskell中的HTTP请求:代理与响应状态检查
|
27天前
|
安全 网络协议 网络安全
解析HTTP代理服务器不稳定致使掉线的关键原因
随着数字化发展,网络安全和隐私保护成为核心需求。HTTP代理服务器掉线原因主要包括:1. 网络问题,如本地网络不稳定、路由复杂;2. 服务器质量差、IP资源不稳定;3. 用户配置错误、超时或请求频率异常;4. IP失效或协议不兼容。这些问题会影响连接稳定性。
64 8
|
1月前
|
缓存 应用服务中间件 Apache
HTTP 范围Range请求
HTTP范围请求是一种强大的技术,允许客户端请求资源的部分内容,提高了传输效率和用户体验。通过正确配置服务器和实现范围请求,可以在视频流、断点续传下载等场景中发挥重要作用。希望本文提供的详细介绍和示例代码能帮助您更好地理解和应用这一技术。
91 19
|
2月前
|
JSON JavaScript 前端开发
什么是HTTP POST请求?初学者指南与示范
HTTP POST请求是一种常用的HTTP方法,主要用于向服务器发送数据。通过合理设置请求头和请求主体,可以实现数据的可靠传输。无论是在客户端使用JavaScript,还是在服务器端使用Node.js,理解和掌握POST请求的工作原理和应用场景,对于Web开发至关重要。
362 18
|
2月前
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
89 2
|
2月前
|
缓存 负载均衡 监控
HTTP代理服务器在网络安全中的重要性
随着科技和互联网的发展,HTTP代理IP中的代理服务器在企业业务中扮演重要角色。其主要作用包括:保护用户信息、访问控制、缓存内容、负载均衡、日志记录和协议转换,从而在网络管理、性能优化和安全性方面发挥关键作用。
95 2
|
2月前
|
Web App开发 大数据 应用服务中间件
什么是 HTTP Range请求(范围请求)
HTTP Range 请求是一种非常有用的 HTTP 功能,允许客户端请求资源的特定部分,从而提高传输效率和用户体验。通过合理使用 Range 请求,可以实现断点续传、视频流播放和按需加载等功能。了解并掌握 HTTP Range 请求的工作原理和应用场景,对开发高效的网络应用至关重要。
221 15
|
2月前
|
Web App开发 网络安全 数据安全/隐私保护
Lua中实现HTTP请求的User-Agent自定义
Lua中实现HTTP请求的User-Agent自定义
|
Web App开发 存储 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
1.HBase依赖于HDFS,HBase按照列族将数据存储在不同的hdfs文件中;MongoDB直接存储在本地磁盘中,MongoDB不分列,整个文档都存储在一个(或者说一组)文件中 (存储) 2.
748 0
|
Web App开发 监控 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
已发现2个内存错误,应用名称(kernel:),日志内容(hangzhou-jishuan-DDS0248 kernel: sbridge: HANDLING MCE MEMORY ERROR hangzhou-jis...
873 0