web-dev-qa-db-de.com

Wie sende ich einen JSON-String in einer POST Anfrage in Go

Ich habe versucht, mit Apiary zu arbeiten, und erstellte eine universelle Vorlage, um JSON an den Mock-Server zu senden, und hatte folgenden Code:

package main

import (
    "encoding/json"
    "fmt"
    "github.com/jmcvetta/napping"
    "log"
    "net/http"
)

func main() {
    url := "http://restapi3.apiary.io/notes"
    fmt.Println("URL:>", url)

    s := napping.Session{}
    h := &http.Header{}
    h.Set("X-Custom-Header", "myvalue")
    s.Header = h

    var jsonStr = []byte(`
{
    "title": "Buy cheese and bread for breakfast."
}`)

    var data map[string]json.RawMessage
    err := json.Unmarshal(jsonStr, &data)
    if err != nil {
        fmt.Println(err)
    }

    resp, err := s.Post(url, &data, nil, nil)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("response Status:", resp.Status())
    fmt.Println("response Headers:", resp.HttpResponse().Header)
    fmt.Println("response Body:", resp.RawText())

}

Dieser Code sendet JSON nicht richtig, aber ich weiß nicht warum. Die JSON-Zeichenfolge kann bei jedem Aufruf unterschiedlich sein. Ich kann Struct nicht dafür verwenden.

164

Ich bin nicht mit dem Nickerchen vertraut, aber mit dem net/http-Paket von Golang funktioniert es gut ( playground

func main() {
    url := "http://restapi3.apiary.io/notes"
    fmt.Println("URL:>", url)

    var jsonStr = []byte(`{"title":"Buy cheese and bread for breakfast."}`)
    req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
    req.Header.Set("X-Custom-Header", "myvalue")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    fmt.Println("response Status:", resp.Status)
    fmt.Println("response Headers:", resp.Header)
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println("response Body:", string(body))
}
371
OneOfOne

sie können einfach post verwenden, um Ihren Json zu posten. 

values := map[string]string{"username": username, "password": password}

jsonValue, _ := json.Marshal(values)

resp, err := http.Post(authAuthenticatorUrl, "application/json", bytes.NewBuffer(jsonValue))
62
gaozhidf

Zusätzlich zum Standard-net/http-Paket können Sie erwägen, mein GoRequest zu verwenden, das net/http umhüllt und Ihnen das Leben erleichtert, ohne sich zu sehr mit Json oder struct zu beschäftigen. Sie können aber auch beide in einer Anfrage kombinieren! (Sie können mehr Details darüber in gorequest github page sehen) 

Am Ende wird Ihr Code also wie folgt:

func main() {
    url := "http://restapi3.apiary.io/notes"
    fmt.Println("URL:>", url)
    request := gorequest.New()
    titleList := []string{"title1", "title2", "title3"}
    for _, title := range titleList {
        resp, body, errs := request.Post(url).
            Set("X-Custom-Header", "myvalue").
            Send(`{"title":"` + title + `"}`).
            End()
        if errs != nil {
            fmt.Println(errs)
            os.Exit(1)
        }
        fmt.Println("response Status:", resp.Status)
        fmt.Println("response Headers:", resp.Header)
        fmt.Println("response Body:", body)
    }
}

Dies hängt davon ab, wie Sie das erreichen möchten. Ich habe diese Bibliothek erstellt, weil ich das gleiche Problem mit Ihnen habe und ich möchte Code, der kürzer ist, mit Json einfach zu verwenden ist und in meinem Codebase- und Produktionssystem wartungsfreundlicher ist.

11
A-letubby

Wenn Sie bereits eine Struktur haben.

type Student struct {
    Name    string `json:"name"`
    Address string `json:"address"`
}

// .....

body := &Student{
    Name:    "abc",
    Address: "xyz",
}

buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(body)
req, _ := http.NewRequest("POST", url, buf)

res, e := client.Do(req)
if e != nil {
    return e
}

defer res.Body.Close()
io.Copy(os.Stdout, res.Body)
0
Ninh Pham