395 Stimmen

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

Ich habe versucht, mit Apiary zu arbeiten und eine universelle Vorlage erstellt, um JSON an den Mock-Server zu senden, und habe diesen 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": "Kaufe Käse und Brot zum Frühstück."}`)    
  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. Der JSON-String kann bei jedem Aufruf anders sein. Ich kann kein Struct dafür verwenden.

711voto

OneOfOne Punkte 88023

Ich bin nicht vertraut mit napping, aber die Verwendung des net/http Pakets von Golang funktioniert gut (Playground):

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

    var jsonStr = []byte(`{"title":"Kaufe Käse und Brot für das Frühstück."}`)
    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, _ := io.ReadAll(resp.Body)
    fmt.Println("response Body:", string(body))
}

173voto

gaozhidf Punkte 2232

Sie können einfach post verwenden, um Ihr JSON zu posten.

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

jsonValue, _ := json.Marshal(values)

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

49voto

Ninh Pham Punkte 5700

Wenn Sie bereits eine Struktur haben.

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
    "os"
)

// .....

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

// .....

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

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

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

defer res.Body.Close()

fmt.Println("response Status:", res.Status)
// Drucken Sie den Body auf die Standardausgabe
io.Copy(os.Stdout, res.Body)

Vollständiges Gist.

14voto

A-letubby Punkte 7818

Abgesehen vom Standard-Net/http-Paket können Sie auch mein GoRequest in Betracht ziehen, das um Net/http herum verpackt ist und Ihr Leben einfacher macht, ohne zu viel über Json oder Strukturen nachzudenken. Aber Sie können auch beide in einer Anfrage mischen und abstimmen! (Weitere Details dazu finden Sie auf der Gorequest-Github-Seite)

Also wird Ihr Code am Ende folgendermaßen aussehen:

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 es erreichen möchten. Ich habe diese Bibliothek erstellt, weil ich dasselbe Problem habe wie Sie und ich Code wünsche, der kürzer ist, einfach mit Json zu verwenden und in meinem Codebase und Produktionssystem wartbarer ist.

7voto

mesutpiskin Punkte 1450

Beispiel Post-Anfrage für http oder https

    //Daten codieren
       postBody, _ := json.Marshal(map[string]string{
          "name":  "Test",
          "email": "Test@Test.com",
       })
       responseBody := bytes.NewBuffer(postBody)
    //Nutze Go's HTTP Post Funktion um die Anfrage zu machen
       resp, err := http.Post("https://postman-echo.com/post", "application/json", responseBody)
    //Fehler behandeln
       if err != nil {
          log.Fatalf("Ein Fehler ist aufgetreten %v", err)
       }
       defer resp.Body.Close()
    //Antwortkörper lesen
       body, err := ioutil.ReadAll(resp.Body)
       if err != nil {
          log.Fatalln(err)
       }
       sb := string(body)
       log.Printf(sb)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X