Golang中如何发送JSON数据到API请求

Golang中如何发送JSON数据到API请求 我需要调用一个需要动态JSON请求体的API,如何发送:

{
"username": "{{username}}"
}
{
"username": "{{username}}",
"password":"{{password}}"
}

1和2取决于具体的API,所以我需要某种动态发送的方式

以下方法没有奏效 😦

b := user.Username
var jsonStr = []byte(b)

req, _ := http.NewRequest("POST", jmb_rid_url,bytes.NewBuffer(jsonStr) )

请求体是空的,如何将这个JSON请求体发送到我的下一个API请求 谢谢


更多关于Golang中如何发送JSON数据到API请求的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

问题在于我的JSON主体始终是动态的,其值不断变化,因此我的JSON结构也应随之改变。是否有像Java中那样简单的方法,可以直接将主体原样发送到下一步?

// 代码示例将在此处

更多关于Golang中如何发送JSON数据到API请求的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


  1. 您能否尝试正确格式化您的代码以便我阅读,或者将其发布到 GitHub Gist 中?目前的格式非常难以理解。

  2. 如果所有其他方法都失败了,您可以尝试使用 map[string]interface{},但这种方法存在一些缺点。

map[string]interface{}

你可能需要在JSON结构体标签中使用 omitempty 标签。

package main

import (
	"encoding/json"
	"fmt"
)

type Demo struct {
	Username string `json:"username"`
	Password string `json:"password,omitempty"`
}

func main() {
	var data Demo
	data.Username = "some-user"
	b, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))

	data.Password = "some-password"
	b, err = json.Marshal(data)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))

}

https://play.golang.org/p/BmoGb6-N2in

感谢分享这个代码片段。我正在尝试修复一段看起来像这样的代码 🙂

else if request_uri != url_check {
check_jmb_token := r.Header.Get("Authorization")
fmt.Println("checking if this is jumbo token or not ", check_jmb_token)
jmb_token := strings.Split(check_jmb_token, ":")
fmt.Println("token checking JMB", jmb_token[0])

if jmb_token[0] == "Bearer JMB_" {
    request_url_jmb := r.RequestURI

    fmt.Println("request_url_jmb--->", request_url_jmb)
    fmt.Println("JMB_ token was recived pass to RID")
    jmb_rid_url := rid_env_url + request_url_jmb
    fmt.Println("jmb_rid_url", jmb_rid_url)
    fmt.Println("jmb_rid_url",jmb_rid_url)
    data := url.Values{}
    if user.Username != ""{

        data.Set("username", user.Username)

    }
    if user.GrantType != ""{

        data.Add("grant_type", user.GrantType)

    }
    if user.GrantType != ""{

        data.Add("password", user.Password)

    }

    payload := data.Encode()
    fmt.Println("mrk see payload",payload)


        fmt.Println("printing body", payload)
        payload_new :=strings.NewReader(payload)
        buf := new(bytes.Buffer)
        buf.ReadFrom(r.Body)
        c_type :=r.Header.Get("Content-Type")
        fmt.Println("c_type",c_type)
        newStr := buf.String()
        var ptr = new(string)
        *ptr = newStr
        fmt.Println("&ptr", &ptr, *ptr)
    
        fmt.Println("----payload_new-----",payload_new)
        fmt.Print("strings.NewReader(user.Username)",strings.NewReader(user.Username))
    

    b := user.Username
    var jsonStr = []byte(b)

        req, _ := http.NewRequest("POST", jmb_rid_url,bytes.NewBuffer(jsonStr) )
        

        jmb_bearer_token := "Bearer " + jmb_token[1]
        fmt.Println("sending request to RID :jmb_bearer_token ", jmb_bearer_token)
        req.Header.Add("Authorization", "Bearer xxxxxxx")
        //fmt.Println("jmb_bearer_token",jmb_bearer_token)
        req.Header.Add("Content-Type", "Application/json")
        //fmt.Println("Content-Type", c_type)
        fmt.Println("see request ------->",req)
        resp, _ := http.DefaultClient.Do(req)
        defer resp.Body.Close()
        bodynew, _ := ioutil.ReadAll(resp.Body)
        fmt.Println("------bodynew--------", string(bodynew))
        fmt.Println("response given: ",resp)
if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
    fmt.Println("here status is 200")
    fmt.Fprintf(w, "%s", bodynew)

}else if resp.StatusCode >=500 && resp.StatusCode <= 599{
        fmt.Println("%T", "final response ", resp)
    fmt.Println("gid_env_url+r.RequestURI", gid_env_url+r.RequestURI)
    fmt.Println("came to gid as rid failed with the following payload ", *ptr)
    pay := strings.NewReader(*ptr)
    req_1, _ := http.NewRequest("POST", gid_env_url+r.RequestURI, pay)
    fmt.Println("Bearerjmb_token[2]", "Bearer "+jmb_token[2])
    jmb_bearer_token_gid := "Bearer " + jmb_token[2]
    req_1.Header.Add("Authorization", jmb_bearer_token_gid)
    req_1.Header.Add("Content-Type", c_type)
    resp_1, _ := http.DefaultClient.Do(req_1)
    defer resp_1.Body.Close()
    fmt.Println("resp_1", resp_1)
    bodynew_1, _ := ioutil.ReadAll(resp_1.Body)
    fmt.Println("RId has failed and we are in GID", string(bodynew_1))
    fmt.Fprintf(w, "%s", bodynew_1)
}else if resp.StatusCode != 200 {

    fmt.Println("here status is ",resp.StatusCode)
    fmt.Fprintf(w, "%s", bodynew)
}else {
    fmt.Println("came into else block of if else in status code ",resp.StatusCode)
}

在Go中发送动态JSON数据到API,需要使用结构体或map来构建请求体,然后使用json.Marshal进行序列化。以下是两种实现方式:

方法1:使用map动态构建JSON

package main

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

func sendDynamicJSON(username, password string, includePassword bool) error {
    // 动态构建请求体
    requestBody := make(map[string]interface{})
    requestBody["username"] = username
    
    if includePassword {
        requestBody["password"] = password
    }
    
    // 序列化为JSON
    jsonData, err := json.Marshal(requestBody)
    if err != nil {
        return err
    }
    
    // 发送请求
    req, err := http.NewRequest("POST", "https://api.example.com/endpoint", bytes.NewBuffer(jsonData))
    if err != nil {
        return err
    }
    
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    
    fmt.Printf("Response status: %s\n", resp.Status)
    return nil
}

// 使用示例
func main() {
    // 发送第一种格式
    err := sendDynamicJSON("john_doe", "", false)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    }
    
    // 发送第二种格式
    err = sendDynamicJSON("john_doe", "secret123", true)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    }
}

方法2:使用结构体和omitempty标签

package main

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

type UserRequest struct {
    Username string `json:"username"`
    Password string `json:"password,omitempty"` // omitempty表示字段为空时忽略
}

func sendJSONWithStruct(username, password string) error {
    userReq := UserRequest{
        Username: username,
        Password: password,
    }
    
    jsonData, err := json.Marshal(userReq)
    if err != nil {
        return err
    }
    
    fmt.Printf("Sending JSON: %s\n", string(jsonData))
    
    req, err := http.NewRequest("POST", "https://api.example.com/endpoint", bytes.NewBuffer(jsonData))
    if err != nil {
        return err
    }
    
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    
    fmt.Printf("Response status: %s\n", resp.Status)
    return nil
}

// 使用示例
func main() {
    // 只有username(password为空会被忽略)
    err := sendJSONWithStruct("john_doe", "")
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    }
    
    // 包含username和password
    err = sendJSONWithStruct("john_doe", "secret123")
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    }
}

方法3:完全动态的方式

package main

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

type APIConfig struct {
    IncludePassword bool
    Username        string
    Password        string
}

func sendDynamicRequest(config APIConfig) error {
    var requestBody map[string]interface{}
    
    if config.IncludePassword {
        requestBody = map[string]interface{}{
            "username": config.Username,
            "password": config.Password,
        }
    } else {
        requestBody = map[string]interface{}{
            "username": config.Username,
        }
    }
    
    jsonData, err := json.Marshal(requestBody)
    if err != nil {
        return err
    }
    
    fmt.Printf("Request body: %s\n", string(jsonData))
    
    req, err := http.NewRequest("POST", "https://api.example.com/endpoint", bytes.NewBuffer(jsonData))
    if err != nil {
        return err
    }
    
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    
    fmt.Printf("Response status: %s\n", resp.Status)
    return nil
}

// 使用示例
func main() {
    // 第一种格式
    config1 := APIConfig{
        IncludePassword: false,
        Username:        "user1",
    }
    
    // 第二种格式
    config2 := APIConfig{
        IncludePassword: true,
        Username:        "user2",
        Password:        "pass123",
    }
    
    err := sendDynamicRequest(config1)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    }
    
    err = sendDynamicRequest(config2)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    }
}

你的代码没有奏效是因为直接使用了字符串而不是序列化的JSON。关键点是使用json.Marshal()将Go数据结构转换为JSON字节,然后通过bytes.NewBuffer()创建请求体。

回到顶部