2015-08-10 20 views
7

Sono nuovo per Go e Gin e sto avendo problemi a stampare il corpo della richiesta completa.gin/golang - Empty Req Body

Voglio essere in grado di leggere il corpo della richiesta da POST di terze parti, ma mi sto richiesta vuoto corpo

curl -u dumbuser:dumbuserpassword -H "Content-Type: application/json" -X POST --data '{"events": "3"}' http://localhost:8080/events 

mio intero codice è il seguente. Qualsiasi puntatore è apprezzato!

package main 

import (
    "net/http" 
    "fmt" 
    "github.com/gin-gonic/gin" 
) 

func main() { 
    router := gin.Default() 
    authorized := router.Group("/", gin.BasicAuth(gin.Accounts{ 
    "dumbuser": "dumbuserpassword", 
    })) 
    authorized.POST("/events", events) 
    router.Run(":8080") 
} 

func events(c *gin.Context) { 
    fmt.Printf("%s", c.Request.Body) 
    c.JSON(http.StatusOK, c) 
} 

risposta

14

Il problema qui è che si sta stampando il valore della stringa di c.Request.Body, che è di tipo di interfaccia ReadCloser.

Cosa si può fare per accertarsi che in realtà contenga il corpo che si desidera leggere il valore di c.Request.Body in una stringa, quindi stamparlo. Questo è solo per il tuo processo di apprendimento!

Apprendimento del codice:

func events(c *gin.Context) { 
     x, _ := ioutil.ReadAll(c.Request.Body) 
     fmt.Printf("%s", string(x)) 
     c.JSON(http.StatusOK, c) 
} 

Tuttavia, questo non è il modo in cui si dovrebbe accedere al corpo della richiesta. Lascia che tu faccia il parsing del corpo per te, usando una rilegatura.

codice più corretto:

type E struct { 
     Events string 
} 

func events(c *gin.Context) { 
     data := &E{} 
     c.Bind(data) 
     fmt.Println(data) 
     c.JSON(http.StatusOK, c) 
} 

Questo è un modo più corretto per accedere ai dati nel corpo, poiché sarà già analizzato per voi. Nota che se leggi prima il corpo, come abbiamo fatto in precedenza nella fase di apprendimento, lo c.Request.Body sarà stato svuotato, e quindi non ci sarà più niente nel corpo che Gin possa leggere.

codice rotto:

func events(c *gin.Context) { 
    x, _ := ioutil.ReadAll(c.Request.Body) 
    fmt.Printf("%s", string(x)) 
    data := &E{} 
    c.Bind(data) // data is left unchanged because c.Request.Body has been used up. 
    fmt.Println(data) 
    c.JSON(http.StatusOK, c) 
} 

Sei probabilmente anche curioso di sapere perchè il JSON tornati da questo endpoint spettacoli e vuoto Request.Body. Questo è per la stessa ragione. Il metodo Marshalling JSON non può serializzare un ReadCloser e quindi si presenta come vuoto.

+0

Grazie, Danver, che ha davvero aiutato ed è stato educativo. –

+1

Cosa c'è da fare se l'associazione fallisce? Dal momento che il Reader è stato svuotato, i dati sono semplicemente andati persi? – sean

+0

Anch'io vorrei conoscere la risposta alla domanda di Sean. –