首页 > 其他分享 >Go语言Http调用之Get、Post请求详解

Go语言Http调用之Get、Post请求详解

时间:2023-08-04 20:23:06浏览次数:48  
标签:body Http err Get url json 参数 Go http

HTTP 调用需要通过 http 包里的 Client 结构体里的 Do 方法去实现,因此需要先声明一个 Client 结构体变量,该结构体可以设置超时时间等配置。

对于一个请求里的 URL,查询参数,请求 method 等参数,需要 http 包里的 Request 结构体去封装。我们可以通过 NewRequestWithContext 或 NewRequest 函数获取一个基础的 Request 结构体指针变量。

NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error)

  • 参数 ctx 为 Context 的接口类型,任意实现 Context 接口的自定义类型都可以作为此参数传递。
  • 参数 method 为 HTTP 方法参数,可选值有 GETPOSTDELETEPUT等。
  • 参数 url 为接口的请求路径。
  • 参数 body,为请求体参数。

通过 client.Do(req) 方法调用之后,返回值有 (*Response, error),第一个是响应结构体参数,第二个是错误参数。通过读取 Response 的 body 的值,可以获取接口的响应体。

一、GET

import (
    "context"
    "fmt"
    "io"
    "net/http"
)

func main() {
    client := http.Client{}
    request, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://localhost:8080/user?name=tom", nil)
    if err != nil {
        return
    }
    request.Header.Set("headerParam", "header")
    resp, err := client.Do(request)
    if err != nil {
        fmt.Println(err)
        return
    }
    bytes, err := io.ReadAll(resp.Body)
    if err != nil {
        return
    }
    defer resp.Body.Close()
    fmt.Println(string(bytes)) // {"code":0,"data":{"list":[{"name":"小明","age":20},{"name":"小红","age":18}]},"message":"success"}
}
  • 需要携带查询参数时,可以直接拼接在 url 字符串上面。
  • header 参数可以通过 request 结构体的 Header 字段的 set 方法或 add 方法进行设置。
  • HTTP 请求响应码可以通过 Response 的 StatusCode 字段进行查看。
  • 接口请求成功之后,通过 io.ReadAll 方法,读取 resp.Body 响应体信息。
  • 除了直接在 url 上拼接 query 参数的方式,我们还可以通过以下方式进行添加 query 参数:
params := url.Values{}
rawUrl, err := url.Parse("http://localhost:8080/user")
if err != nil {
    return
}
params.Set("name", "tom")
rawUrl.RawQuery = params.Encode()
u := rawUrl.String()

通过 url.Values 结构体的 set 方法设置 query参数,url 通过 url.Parse 函数生成一个 URL 结构体指针变量,rawUrl.RawQuery = params.Encode() 通过这行代码将 query 参数和 url 进行绑定,最后通过 String() 方法将 url 转换成 string 类型。

二、POST

发起 HTTP POST 请求时,携带 json 格式的 body 参数是最常见的,这是因为 json 格式的参数可读性好,对于层级结构较为复杂的数据也能应对,并且这符合 RestFul API 的规范。因此以下的示例为:发送 HTTP POST 请求,并携带 json 类型的 body 参数。

import (
    "bytes"
    "context"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

type User struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

func main() {
    client := http.Client{}

    user := User{
        Username: "123456",
        Password: "12346",
    }
    dataByte, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
    }
    bodyReader := bytes.NewReader(dataByte)

    request, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://localhost:8080/user", bodyReader)
    if err != nil {
        return
    }
    request.Header.Set("Content-Type", "application/json")
    resp, err := client.Do(request)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("statusCode: ", resp.StatusCode)
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return
    }
    defer resp.Body.Close()
    fmt.Println(string(body))
}
  • 首先定义 User 结构体,创建结构体变量 user,通过 json.Marshal 函数,将 user 转成 []byte 数据,然后通过 bytes.NewReader 函数,将 []byte 数据转成 Reader 指针变量。
  • http.NewRequestWithContext 函数,最后一个参数是为 body 参数,接收的变量类型是 Reader 接口的实现体。第一步将 user 转成 Reader 指针变量就是为了在这里进行传递。
  • 传递 json 类型的 body 参数,需要在请求头参数里设置 Content-Type 的值为 application/json

如果是发送 application/x-www-form-urlencoded 类型的表单数据,需要改写 body 参数的生成代码:

values := url.Values{}
values.Set("username", "1234")
values.Set("password", "1234")
bodyReader := strings.NewReader(values.Encode())

本文通过 POST 请求,介绍了如何传递 json 类型和 application/x-www-form-urlencoded 类型的 body 参数。对于 HTTP 中的 query 参数和 body 参数的如何传递,上下两篇文章已经通过例子进行介绍。虽然举的例子是 GET 和 POST 请求,如果想要调用 PUTDELETE 等请求,只需要在 NewRequestWithContext 函数中,指定第二个参数为 http.MethodPuthttp.MethodDelete 等就行。

标签:body,Http,err,Get,url,json,参数,Go,http
From: https://www.cnblogs.com/beatle-go/p/17606980.html

相关文章

  • 扩展Django:实现自己的manage命令
    我们都用过Django的django-admin.py和manage.py。django-admin.py是一个命令行工具,可以执行一些管理任务,比如创建Django项目。而manage.py是在创建每个Djangoproject时自动添加在项目目录下的,只是对manage.py的一个简单包装,其功能是将Djangoproject放到sys.path目录中,同时设置DJ......
  • RunnerGo条件控制器使用方法
    在做性能测试时我们需要根据业务需求、业务场景来配置测试脚本,举个例子:在登录注册场景中,可能会有账号密码全部正确、账号格式错误、密码错误等多种情况,这里的“登录/注册”事件可以视为一个场景。一个真实业务中的场景,不仅是独立接口的串联,还会涉及到条件分支、参数提取、断言等一......
  • HttpClient Https请求 基础连接已经关闭,发送时发生错误
    可能有以下几个原因:证书问题:服务端证书无效或者客户端不信任服务器证书会导致握手失败。你需要检查服务端证书是否有效,是否由受信任的证书颁发机构(CA)签署。TLS版本不兼容:服务端只支持较新版本的TLS,而客户端使用的.NET版本较旧,其中包含的TLS版本与服务端不兼容。尝试升级.......
  • RunnerGo条件控制器使用方法
    在做性能测试时我们需要根据业务需求、业务场景来配置测试脚本,举个例子:在登录注册场景中,可能会有账号密码全部正确、账号格式错误、密码错误等多种情况,这里的“登录/注册”事件可以视为一个场景。一个真实业务中的场景,不仅是独立接口的串联,还会涉及到条件分支、参数提取、断言等一......
  • Django-4.2博客开发教程:初识模板(九)
    一、模板简介为了更好的维护和展示页面数据,使用直接返回数据显然是呆板的,不够美观,不够灵活,所以要使用模板。模板一般都放到项目根目录下的templates文件夹里。模板包含一些基础的HTML代码和一些特殊的语法,通过特殊的语法将数据动态的插入HTML页面中。特殊的语法中有一些变量......
  • GO:用链表实现栈的操作
         ......
  • 华为开发者大会2023(HDC.Together)正式开启,一文带你了解全新鸿蒙世界
    (中国,东莞,2023年8月4日)2023年华为开发者大会(HDC.Together)今天正式开幕,华为发布HarmonyOS4、全新升级的鸿蒙开发套件、HarmonyOSNext开发者预览版本等一系列领先技术,为用户提供前所未有的革新体验,帮助开发者更高效地打造创新的智能终端和应用服务。华为常务董事、终端BGCEO、智能......
  • GO 数据结构操作:栈
        ......
  • mongo
    MongoDB教程什么是MongoDBMongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是......
  • 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务(转)
    Spring,构建Java™平台和EnterpriseEdition(JavaEE)应用程序的著名框架,现在在其模型-视图-控制器(Model-View-Controller,MVC)层支持具象状态传输(REST)。RESTfulweb服务根据客户端请求生成多个具象(representations)很重要。在本篇文章中,学习使用HttpMessageConverter 生成......