J'ai donc ce qui suit, qui semble incroyablement hacky, et je me suis dit que Go a des bibliothèques mieux conçues que cela, mais je ne trouve pas d'exemple de Go traitant une demande POST de données JSON. Ce sont tous des POST.
Voici un exemple de demande: curl -X POST -d "{\"test\": \"that\"}" http://localhost:8082/test
Et voici le code, avec les journaux intégrés:
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))
}
Il doit y avoir un meilleur moyen, non? Je suis juste perplexe pour trouver quelle pourrait être la meilleure pratique.
(Go est également connu sous le nom de Golang pour les moteurs de recherche, et mentionné ici pour que d'autres puissent le trouver.)
curl -X POST -H 'Content-Type: application/json' -d "{\"test\": \"that\"}"
, alorsreq.Form["test"]
devrait revenir"that"
Réponses:
Veuillez utiliser à la
json.Decoder
place dejson.Unmarshal
.la source
defer req.Body.Close()
De la documentation: "Le serveur fermera le corps de la demande. Le gestionnaire ServeHTTP n'a pas besoin de le faire." Aussi pour répondre à @thisisnotabus, dans la documentation: "Pour les demandes de serveur, le corps de la demande est toujours non nul mais retournera EOF immédiatement quand aucun corps n'est présent" golang.org/pkg/net/http/#Requestjson.Decoder
. Il est destiné aux flux d'objets JSON, pas à un seul objet. Il n'est pas plus efficace pour un seul objet JSON car il lit l'intégralité de l'objet en mémoire. Il a un inconvénient: si des déchets sont inclus après l'objet, ils ne se plaindront pas. En fonction de quelques facteurs, il sejson.Decoder
peut que le corps ne soit pas entièrement lu et que la connexion ne puisse pas être réutilisée.Vous devez lire
req.Body
. LaParseForm
méthode est en train de lire lereq.Body
puis de l'analyser au format codé HTTP standard. Ce que vous voulez, c'est lire le corps et l'analyser au format JSON.Voici votre code mis à jour.
la source
req.ParseForm()
, ce que je faisais dans des tentatives précédentes pour essayer de résoudre ce problème, avant d'essayer de lire lereq.Body
, il semble effacer le corps etunexpected end of JSON input
est jeté lorsque vous allez àUnmarshal
(au moins en 1.0.2)json.NewDecoder(req.Body)
sont également correctes.Je me rendais fou avec ce problème exact. Mon Marshaller JSON et Unmarshaller ne remplissaient pas ma structure Go. J'ai ensuite trouvé la solution sur https://eager.io/blog/go-and-json :
Après cela, mon Marshaller et Unmarshaller ont parfaitement fonctionné!
la source
Il y a deux raisons pour lesquelles
json.Decoder
il faut privilégierjson.Unmarshal
- qui ne sont pas abordées dans la réponse la plus populaire de 2013:go 1.10
introduit une nouvelle méthode json.Decoder.DisallowUnknownFields () qui répond au souci de détecter les entrées JSON indésirablesreq.Body
est déjà unio.Reader
. La lecture de l'intégralité de son contenu, puis l'exécutionjson.Unmarshal
gaspille des ressources si le flux était, disons un bloc de 10 Mo de JSON invalide. L'analyse du corps de la demande, avecjson.Decoder
, lors de son flux , déclencherait une erreur d'analyse précoce si un JSON non valide était rencontré. Le traitement des flux d'E / S en temps réel est la solution préférée .Répondre à certains des commentaires des utilisateurs sur la détection de mauvaises entrées utilisateur:
Pour appliquer les champs obligatoires et les autres vérifications d'assainissement, essayez:
Terrain de jeux
Sortie typique:
la source
J'ai trouvé l'exemple suivant de la documentation vraiment utile (source ici ).
La clé ici étant que l'OP cherchait à décoder
... auquel cas nous supprimerions le
const jsonStream
, et remplacerions leMessage
struct par letest_struct
:Mise à jour : j'ajouterais également que cet article fournit également d'excellentes données sur la réponse avec JSON. L'auteur explique
struct tags
, dont je n'étais pas au courant.Étant donné que JSON ne ressemble pas normalement
{"Test": "test", "SomeKey": "SomeVal"}
, mais plutôt{"test": "test", "somekey": "some value"}
, vous pouvez restructurer votre structure comme ceci:... et maintenant votre gestionnaire analysera JSON en utilisant "une clé" par opposition à "une clé" (que vous utiliserez en interne).
la source
la source