Jadi saya memiliki yang berikut ini, yang tampaknya sangat tidak rapi, dan saya telah berpikir pada diri saya sendiri bahwa Go memiliki perpustakaan yang dirancang lebih baik daripada ini, tetapi saya tidak dapat menemukan contoh Go menangani permintaan POST data JSON. Mereka semua membentuk POST.
Berikut ini contoh permintaan: curl -X POST -d "{\"test\": \"that\"}" http://localhost:8082/test
Dan ini kodenya, dengan log yang disematkan:
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))
}
Pasti ada cara yang lebih baik, bukan? Saya hanya bingung menemukan apa yang bisa menjadi praktik terbaik.
(Go juga dikenal sebagai Golang ke mesin pencari, dan disebutkan di sini sehingga orang lain dapat menemukannya.)
curl -X POST -H 'Content-Type: application/json' -d "{\"test\": \"that\"}"
, makareq.Form["test"]
harus kembali"that"
Jawaban:
Silakan gunakan
json.Decoder
sebagai gantijson.Unmarshal
.sumber
defer req.Body.Close()
Dari dokumen: "Server akan menutup tubuh permintaan. ServeHTTP Handler tidak perlu." Juga untuk menjawab @ thisisnotabus, dari dokumen: "Untuk permintaan server, Badan Permintaan selalu non-nil tetapi akan segera mengembalikan EOF ketika tidak ada badan" golang.org/pkg/net/http/#Requestjson.Decoder
. Ini dimaksudkan untuk stream objek JSON, bukan objek tunggal. Ini tidak lebih efisien untuk objek JSON tunggal karena membaca seluruh objek menjadi memori. Ini memiliki kelemahan bahwa jika sampah dimasukkan setelah objek tidak akan mengeluh. Tergantung pada beberapa faktor,json.Decoder
mungkin tubuh tidak sepenuhnya terbaca dan koneksi tidak akan dapat digunakan kembali.Anda perlu membaca
req.Body
. TheParseForm
Metode membaca darireq.Body
dan kemudian parsing itu dalam standar HTTP format yang disandikan. Yang Anda inginkan adalah membaca isi dan menguraikannya dalam format JSON.Ini kode Anda yang diperbarui.
sumber
req.ParseForm()
, yang saya lakukan dalam upaya sebelumnya untuk mencoba memecahkan masalah ini, sebelum Anda mencoba dan membacareq.Body
, sepertinya membersihkan tubuh danunexpected end of JSON input
dibuang ketika Anda pergi keUnmarshal
(setidaknya dalam 1.0.2)json.NewDecoder(req.Body)
juga benar.Saya membuat diri saya gila dengan masalah ini. JSON Marshaller dan Unmarshaller saya tidak mengisi Go struct saya. Kemudian saya menemukan solusinya di https://eager.io/blog/go-and-json :
Setelah itu, Marshaller dan Unmarshaller saya bekerja dengan sempurna!
sumber
Ada dua alasan mengapa
json.Decoder
lebih disukai daripadajson.Unmarshal
- yang tidak dibahas dalam jawaban paling populer dari 2013:go 1.10
memperkenalkan metode baru json.Decoder.DisallowUnknownFields () yang membahas masalah mendeteksi input JSON yang tidak diinginkanreq.Body
sudah menjadiio.Reader
. Membaca seluruh isinya dan kemudian melakukanjson.Unmarshal
pemborosan sumber daya jika alirannya, katakanlah blok 10MB JSON tidak valid. Mem-parsing badan permintaan, denganjson.Decoder
, saat streaming masuk akan memicu kesalahan parse awal jika JSON tidak valid ditemukan. Pengolahan I / O stream secara realtime adalah disukai go-cara .Mengatasi beberapa komentar pengguna tentang mendeteksi input pengguna yang buruk:
Untuk menegakkan bidang wajib, dan pemeriksaan sanitasi lainnya, cobalah:
Tempat bermain
Output khas:
sumber
Saya menemukan contoh berikut dari dokumen sangat membantu (sumber di sini ).
Kuncinya di sini adalah bahwa OP ingin memecahkan kode
... dalam hal ini kita akan menjatuhkan
const jsonStream
, dan menggantiMessage
struct dengantest_struct
:Pembaruan : Saya juga akan menambahkan bahwa posting ini menyediakan beberapa data hebat tentang menanggapi dengan JSON juga. Penulis menjelaskan
struct tags
, yang tidak saya sadari.Karena JSON biasanya tidak terlihat seperti
{"Test": "test", "SomeKey": "SomeVal"}
, tetapi{"test": "test", "somekey": "some value"}
Anda dapat merestrukturisasi struct Anda seperti ini:... dan sekarang pawang Anda akan menguraikan JSON menggunakan "some-key" sebagai kebalikan dari "SomeKey" (yang akan Anda gunakan secara internal).
sumber
sumber