【Golang 接口自动化02】使用标准库net/http发送Post请求

目录

写在前面

发送Post请求

示例代码

源码分析

Post请求参数解析

响应数据解析

验证

发送Json/XMl

Json请求示例代码

xml请求示例代码

总结

资料获取方法


写在前面

上一篇我们介绍了使用 net/http 发送get请求,因为考虑到篇幅问题,把Post单独拎了出来,我们在这一篇一起从源码来了解一下Golang的Post请求。

发送Post请求

net/http发送Post请求很容易,下面的代码我们和Get请求一样,把响应的内容的信息打印出来了,细心的朋友可能会发现,在参数传递、和结果解析时用了三种不同的方式,我们将在后面进行解析。

示例代码

package mainimport ("bytes""fmt""io/ioutil""net/http""reflect""strings"
)func main() {resp, err := http.Post("http://httpbin.org/post","application/x-www-form-urlencoded",strings.NewReader("name=Detector&mobile=1xxxxxxxx"))if err != nil {fmt.Println(err)return}defer resp.Body.Close()headers := resp.Header// headers 打印报文头部信息for k, v := range headers {fmt.Printf("%v, %v\n", k, v) // %v 打印interfac{}的值}// 打印响应信息内容fmt.Printf("响应状态:%s,响应码: %d\n", resp.Status, resp.StatusCode)fmt.Printf("协议:%s\n", resp.Proto)fmt.Printf("响应内容长度: %d\n", resp.ContentLength)fmt.Printf("编码格式:%v\n", resp.TransferEncoding) // 未指定时为空fmt.Printf("是否压缩:%t\n", resp.Uncompressed)fmt.Println(reflect.TypeOf(resp.Body)) // *http.gzipReaderfmt.Println(resp.Body)buf := bytes.NewBuffer(make([]byte, 0, 512))length, _ := buf.ReadFrom(resp.Body)fmt.Println(len(buf.Bytes()))fmt.Println(length)fmt.Println(string(buf.Bytes()))body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println(err)return}fmt.Println(string(body))
}

源码分析

Post请求参数解析

我们首先来看一下C:\Go\src\net\http\client.go中Post和Get请求的源码:

func Get(url string) (resp *Response, err error) {return DefaultClient.Get(url)
}
func Post(url string, contentType string, body io.Reader) (resp *Response, err error) {return DefaultClient.Post(url, contentType, body)
}

从上面的定义可以看出,Post请求的参数比Get复杂一些,不仅要传递string类型contentType还有传递io.Reader类型的body体。可能有的小伙伴就有疑问了-- io.Reader类型的body体是不是意味着我们一定要使用io.Reader模块来获取数据呢?

答案当然是否定的。

我们通过阅读源码,来找想要的答案。

找到其最小粒度的接口是一个比较好的手段,io.Reader最小粒度的接口的定义在C:\Go\src\io\io.go中:

type Reader interface {Read(p []byte) (n int, err error)
}

在我前面的一篇博客【Golang】基础10 Go语言最精妙的设计--interface中学习过 interface,其中有两句话是这样的:

interface类型定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。如果我们定义了一个interface的变量,那么这个变量里面可以存实现这个interface的任意类型的对象。

针对io.Reader的定义翻译一下就是,只要实现了Read(p []byte) (n int, err error)方法的类型,就可以存储io.Reader,从而作为Post请求的Body参数。

我们接着来看看响应resp中数据的定义。

响应数据解析

在上一篇我们对http请求中的数据进行了介绍,这一次我们针对resp.Body进行展开。

C:\Go\src\net\http\response.go中我们可以看到它的类型Body io.ReadCloser,在C:\Go\src\io\io.go中我们可以看到对应的定义是这样的:

type ReadCloser interface {ReaderCloser
}

而Reader就是我们上面分析的过的请求body定义的Reader,而Closer是一个error类型:

type Closer interface {Close() error
}

根据我们上面的结论-- 定义的某个接口的变量可以存储同样实现该接口的任意类型对象,即是说任意类型,只要实现了 Reader和 Closer 即可以用来解析resp.Body

那我们来验证一下示例里面使用的三种方法是不是符合我们这个结论。

验证

  • strings.NewReader
    我们可以在C:\Go\src\strings\reader.go看到 Reader类型的 Read方法:

  • bytes.NewBuffer
    我们可以在C:\Go\src\bytes\buffer.go看到 Buffer类型的 Read方法:

  • ioutil.ReadAll
    我们可以在C:\Go\src\io\ioutil\ioutil.go看到 io.Reader类型的 ReadAllClose() error方法:

发送Json/XMl

在了解了上面的知识之后,我们再来看发送Json、XML数据等就比较简单了。

Json请求示例代码

func JsonReq() {info := make(map[string]interface{})info["name"] = "Detector"info["age"] = 15info["loc"] = "深圳"// 将map解析未[]byte类型bytesData, _ := json.Marshal(info)// 将解析之后的数据转为*Reader类型reader := bytes.NewReader(bytesData)println(reader)resp, _ := http.Post("http://httpbin.org/post","application/json",reader)body, _ := ioutil.ReadAll(resp.Body)fmt.Println(string(body))
}

代码里面给了一些注释,我们把要发送的数据转化为了 *Reader类型,然后就可以直接发送了。(我们从上面的源码分析可以知道这个类型是可以存储io.Reader的数据的)

xml请求示例代码

func XMLReq() {xml := `<?xml version="1.0" encoding="UTF-8"?><resources><string name="VideoLoading">Loading video…</string><string name="ApplicationName">what</string></resources>`bytesData := strings.NewReader(xml)resp, _ := http.Post("http://httpbin.org/post","application/xml",bytesData)body, _ := ioutil.ReadAll(resp.Body)fmt.Println(string(body))
}

总结

  • Json、xml请求
  • 请求、响应数据简析
  • interface概念复习

资料获取方法

【留言777】

各位想获取源码等教程资料的朋友请点赞 + 评论 + 收藏,三连!

三连之后我会在评论区挨个私信发给你们~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 缓存 Cache 入门

Spring Boot 缓存 Cache 入门 1.概述 在系统访问量越来越大之后&#xff0c;往往最先出现瓶颈的往往是数据库。而为了减少数据库的压力&#xff0c;我们可以选择让产品砍掉消耗数据库性能的需求。 当然也可以引入缓存,在引入缓存之后&#xff0c;我们的读操作的代码&#xff…

介绍壹牛NFT数字艺术藏品数藏源码

这个版本新增了不少功能&#xff0c;也修复了一些地方。 1.平台新增用户找回密码功能 2.平台新增短信注册&#xff08;实名制功能&#xff09; 3.平台新增主图后台添加功能 4.平台修复相关问题&#xff0c;系统高效运行 5、H5端与APP端在新UI完美适配 6、加入宝盒功能&…

Java方法的使用(重点:形参和实参的关系、方法重载、递归)

目录 一、Java方法 * 有返回类型&#xff0c;在方法体里就一定要返回相应类型的数据。没有返回类型&#xff08;void&#xff09;&#xff0c;就不要返回&#xff01;&#xff01; * 方法没有声明一说。与C语言不同&#xff08;C语言是自顶向下读取代码&#xff09;&#…

基于SpringBoot+Vue的车辆充电桩管理系统设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

STM32 LWIP UDP 一对一 一对多发送

STM32 LWIP UDP通信 前言设置 IP 地址UDP函数配置实验结果单播发送&#xff0c;一对一发送广播发送&#xff0c;一对多发送 可能遇到的问题总结 前言 之前没有接触过网络的通信&#xff0c;工作需要 UDP 接收和发送通信&#xff0c;在网上没有找到一对一、一对多的相关例程&am…

什么是SVM算法?硬间隔和软间隔的分类问题

SVM全称是supported vector machine(支持向量机)&#xff0c;即寻找到一个超平面使样本分成两类&#xff0c;并且间隔最大。 SVM能够执行线性或⾮线性分类、回归&#xff0c;甚至是异常值检测任务。它是机器学习领域最受欢迎的模型之一。SVM特别适用于中小型复杂数据集的分类。…

CentOS 8 错误: Error setting up base repository

配置ip、掩码、网关、DNS VMware网关可通过如下查看 打开网络连接 配置镜像的地址 vault.centos.org/8.5.2111/BaseOS/x86_64/os/

通过String字符生成base64编码在生成图片

* base64转图片 //对字节数组字符串进行Base64解码并生成图片 * param base64str base64码 * return // param savePath 图片路径private static final String savePath"image_ver\\verifyCode"; 判断是否为base64编码 public static void mainDD…

【JavaEE初阶】Servlet (三)MessageWall

在我们之前博客中写到的留言墙页面,有很严重的问题:(留言墙博客) 如果刷新页面/关闭页面重开,之前输入的消息就不见了.如果一个机器上输入了数据,第二个机器上是看不到的. 针对以上问题,我们的解决思如如下: 让服务器来存储用户提交的数据,由服务器保存. 当有新的浏览器打开页…

基于java的坦克大战游戏的设计与实现--答辨PPT--【毕业论文】

文章目录 本系列校训毕设的技术铺垫PPT主体层次封面页目录页&#xff1a;设计工具与相关技术&#xff1a;系统分析总体设计&#xff1a;详细设计测试结论&#xff1a; 小技巧 本系列校训 互相伤害互相卷&#xff0c;玩命学习要你管&#xff0c;天生我才必有用&#xff0c;我命…

React(1)——快速入门

一、React背景简介 官网和资料 英文官网: https://reactjs.org/中文官网: 快速入门 – React (docschina.org) 3、如果JS基础忘了及时查看文档&#xff1a;JavaScript - 学习 Web 开发 |多核 (mozilla.org) JavaScript - 标签 - 汤姆大叔 - 博客园 (cnblogs.com) 4、React…

Neo4j图数据基本操作

Neo4j 文章目录 Neo4jCQL结点和关系增删改查匹配语句 根据标签匹配节点根据标签和属性匹配节点删除导入数据目前的问题菜谱解决的问题 命令行窗口 neo4j.bat console 导入rdf格式的文件 :GET /rdf/ping CALL n10s.graphconfig.init(); //初始化 call n10s.rdf.import.fetch(&q…

【软件测试】webdriver常用API演示(Java+IDEA+chrome浏览器)

1.元素定位方法 对象的定位应该是自动化测试的核心&#xff0c;要想操作一个对象&#xff0c;首先应该识别这个对象。一个对象就是一个人一样&#xff0c;他会有各种的特征&#xff08;属性&#xff09;&#xff0c;如比我们可以通过一个人的身份证号&#xff0c;姓名&#xf…

Redis 笔记,基本数据类型、持久化、主从、集群等等问题

标题 &#x1f600;&#x1f600;&#x1f600;创作不易&#xff0c;各位看官点赞收藏. 文章目录 标题Redis 基础笔记1、安装及环境搭建2、Redis 数据类型2.1、String2.2、List2.3、Hash2.4、Set2.5、Zset2.6、BitMap2.7、HyperLogLog2.8、Geospatial2.9、Stream 3、Redis 持久…

「BLIP 微调指南」以 Image-Text Captioning 任务为例

前言&#xff1a;近日需要用到 BLIP 微调下游任务&#xff0c;搜索发觉如今并无 BLIP 微调教程&#xff0c;下面就以 Image-Text Captioning 任务为例&#xff0c;演示如何完成 BLIP 模型在自己数据集上的微调。 目录 1. BLIP 介绍2. 关键代码定位3. 关键参数赋值4. 模型定义&a…

HTML一些基础知识

1、Web标准&#xff1a;主要包含结构、表现、行为。结构用于对网页元素进行整理和分类&#xff0c;主要指HTML。表现用于设置网页元素的板式、颜色、大小等外观样式&#xff0c;主要指的是CSS。行为主要指的是网页模型的定义以及交互的编写&#xff0c;主要是js文件。 Html相当…

DAY1,Qt [ 手动实现登录框(信息调试类,按钮类,行编辑器类,标签类的使用)]

1.手动实现登录框&#xff1b; ---mychat.h---头文件 #ifndef MYCHAT_H #define MYCHAT_H#include <QWidget> #include <QDebug> //打印信息 #include <QIcon> //图标 #include <QPushButton> //按钮 #include <QLineEdit> //行编辑器类 #in…

尚硅谷大数据项目《在线教育之采集系统》笔记002

视频地址&#xff1a;尚硅谷大数据项目《在线教育之采集系统》_哔哩哔哩_bilibili 目录 P032 P033 P033 P034 P035 P036 P032 P033 # 1、定义组件&#xff0c;为各组件命名 a1.sources r1 a1.channels c1 a1.sinks - k1# 2、配置sources&#xff0c;描述source a1.sour…

微服务划分的原则

微服务的划分 微服务的划分要保证的原则 单一职责原则 1、耦合性也称块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密&#xff0c;其耦合性就越强&#xff0c;模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及…

hive删除数据进行恢复

在实际开发或生产中&#xff0c;hive表如果被误删&#xff0c;如被truncate或是分区表的分区被误删了&#xff0c;只要在回收站的清空周期内&#xff0c;是可以恢复数据的&#xff0c;步骤如下&#xff1a; &#xff08;1&#xff09; 先找到被删除数据的存放目录&#xff0c;…