Así que tengo lo siguiente, que parece increíblemente hacky, y he estado pensando que Go tiene bibliotecas mejor diseñadas que esta, pero no puedo encontrar un ejemplo de Go manejando una solicitud POST de datos JSON. Todos son POST de forma.
Aquí hay un ejemplo de solicitud: curl -X POST -d "{\"test\": \"that\"}" http://localhost:8082/test
Y aquí está el código, con los registros incrustados:
package main
import (
"encoding/json"
"log"
"net/http"
)
type test_struct struct {
Test string
}
func test(rw http.ResponseWriter, req *http.Request) {
req.ParseForm()
log.Println(req.Form)
//LOG: map[{"test": "that"}:[]]
var t test_struct
for key, _ := range req.Form {
log.Println(key)
//LOG: {"test": "that"}
err := json.Unmarshal([]byte(key), &t)
if err != nil {
log.Println(err.Error())
}
}
log.Println(t.Test)
//LOG: that
}
func main() {
http.HandleFunc("/test", test)
log.Fatal(http.ListenAndServe(":8082", nil))
}
Tiene que haber una mejor manera, ¿verdad? Estoy perplejo al encontrar cuál podría ser la mejor práctica.
(Go también se conoce como Golang para los motores de búsqueda, y se menciona aquí para que otros puedan encontrarlo).
curl -X POST -H 'Content-Type: application/json' -d "{\"test\": \"that\"}"
, entoncesreq.Form["test"]
debería regresar"that"
Respuestas:
Por favor, use en
json.Decoder
lugar dejson.Unmarshal
.fuente
defer req.Body.Close()
De los documentos: "El servidor cerrará el cuerpo de la solicitud. El controlador ServeHTTP no necesita". También para responder a @thisisnotabus, de los documentos: "Para las solicitudes del servidor, el cuerpo de la solicitud siempre es nulo, pero devolverá EOF inmediatamente cuando no hay ningún cuerpo presente" golang.org/pkg/net/http/#Requestjson.Decoder
. Está destinado a secuencias de objetos JSON, no a un solo objeto. No es más eficiente para un solo objeto JSON ya que lee todo el objeto en la memoria. Tiene el inconveniente de que si se incluye basura después del objeto, no se quejará. Dependiendo de algunos factores, esjson.Decoder
posible que no lea completamente el cuerpo y la conexión no sea elegible para su reutilización.Necesitas leer de
req.Body
. ElParseForm
método lee desdereq.Body
y luego lo analiza en formato estándar codificado HTTP. Lo que desea es leer el cuerpo y analizarlo en formato JSON.Aquí está tu código actualizado.
fuente
req.ParseForm()
, lo que estaba haciendo en intentos anteriores de tratar de resolver este problema, antes de intentar leerloreq.Body
, parece despejar el cuerpo yunexpected end of JSON input
se arroja cuando va aUnmarshal
(al menos en 1.0.2)json.NewDecoder(req.Body)
también son correctas.Me estaba volviendo loco con este problema exacto. Mi JSON Marshaller y Unmarshaller no poblaban mi estructura Go. Luego encontré la solución en https://eager.io/blog/go-and-json :
¡Después de eso, mi Marshaller y Unmarshaller funcionaron perfectamente!
fuente
Hay dos razones por las
json.Decoder
que se debe preferir a lasjson.Unmarshal
que no se abordan en la respuesta más popular de 2013:go 1.10
introdujo un nuevo método json.Decoder.DisallowUnknownFields () que aborda la preocupación de detectar entradas JSON no deseadasreq.Body
ya es unio.Reader
. Leer todo su contenido y luegojson.Unmarshal
desperdiciar recursos si la transmisión fue, digamos un bloque de 10 MB de JSON no válido. Analizar el cuerpo de la solicitud, conjson.Decoder
, a medida que se transmite , provocaría un error de análisis temprano si se encuentra un JSON no válido. Procesamiento de E / S flujos en tiempo real es el preferido ir vías .Abordar algunos de los comentarios de los usuarios sobre la detección de entradas incorrectas del usuario:
Para hacer cumplir los campos obligatorios y otras comprobaciones de saneamiento, intente:
Patio de recreo
Salida típica:
fuente
Encontré el siguiente ejemplo de los documentos realmente útil (fuente aquí ).
La clave aquí es que el OP estaba buscando decodificar
... en cuyo caso soltaríamos
const jsonStream
, y reemplazaríamos laMessage
estructura contest_struct
:Actualización : también agregaría que esta publicación también proporciona excelentes datos sobre cómo responder con JSON. El autor explica
struct tags
, de lo que no estaba al tanto.Dado que JSON normalmente no se ve así
{"Test": "test", "SomeKey": "SomeVal"}
, sino{"test": "test", "somekey": "some value"}
que puede reestructurar su estructura de esta manera:... y ahora su controlador analizará JSON usando "alguna clave" en lugar de "SomeKey" (que utilizará internamente).
fuente
fuente