Обработка запроса JSON Post в Go
Итак, у меня есть следующее, что кажется невероятно хакерским, и я думал про себя, что Go имеет более совершенные библиотеки, чем это, но я не могу найти пример обработки запроса POST данных JSON. Все они формируют посты.
вот пример запрос: curl -X POST -d "{"test": "that"}" http://localhost:8082/test
и вот код, с логами встроенных:
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))
}
там должен быть лучший способ? Я просто в тупике в поиске того, что может быть лучшей практикой.
(Go также известен как Golang для поисковых систем и упоминается здесь, чтобы другие могли его найти.)
4 ответов:
пожалуйста, используйте
json.Decoderвместоjson.Unmarshal.func test(rw http.ResponseWriter, req *http.Request) { decoder := json.NewDecoder(req.Body) var t test_struct err := decoder.Decode(&t) if err != nil { panic(err) } log.Println(t.Test) }
вам нужно прочитать от
req.Body. ЭлементParseFormметод считывает изreq.Bodyи затем разбор его в стандартном формате http-кодирования. Вы хотите прочитать тело и проанализировать его в формате JSON.вот ваш код обновлен.
package main import ( "encoding/json" "log" "net/http" "io/ioutil" ) type test_struct struct { Test string } func test(rw http.ResponseWriter, req *http.Request) { body, err := ioutil.ReadAll(req.Body) if err != nil { panic(err) } log.Println(string(body)) var t test_struct err = json.Unmarshal(body, &t) if err != nil { panic(err) } log.Println(t.Test) } func main() { http.HandleFunc("/test", test) log.Fatal(http.ListenAndServe(":8082", nil)) }
я сводил себя с ума именно с этой проблемой. Мой JSON Marshaller и Unmarshaller не заполняли мою структуру Go. Затем я нашел решение в https://eager.io/blog/go-and-json:
" Как и во всех структурах в Go, важно помнить, что только поля с заглавной первой буквой видны внешним программам, таким как JSON Marshaller."
после этого, мой marshaller и вызывается работал отлично!
я нашел следующий пример из документов действительно полезным (source здесь).
package main import ( "encoding/json" "fmt" "io" "log" "strings" ) func main() { const jsonStream = ` {"Name": "Ed", "Text": "Knock knock."} {"Name": "Sam", "Text": "Who's there?"} {"Name": "Ed", "Text": "Go fmt."} {"Name": "Sam", "Text": "Go fmt who?"} {"Name": "Ed", "Text": "Go fmt yourself!"} ` type Message struct { Name, Text string } dec := json.NewDecoder(strings.NewReader(jsonStream)) for { var m Message if err := dec.Decode(&m); err == io.EOF { break } else if err != nil { log.Fatal(err) } fmt.Printf("%s: %s\n", m.Name, m.Text) } }ключевым моментом здесь является то, что ОП искал, чтобы раскодировать
type test_struct struct { Test string }...в этом случае мы бы отбросить
const jsonStreamи заменитьMessageструктура сtest_struct:func test(rw http.ResponseWriter, req *http.Request) { dec := json.NewDecoder(req.Body) for { var t test_struct if err := dec.Decode(&t); err == io.EOF { break } else if err != nil { log.Fatal(err) } log.Printf("%s\n", t.Test) } }обновление: я бы также добавил, что этот пост предоставляет некоторые большие данные об ответе с JSON, а также. Автор объясняет
struct tags, о котором я не знал.так как JSON обычно не выглядит как
{"Test": "test", "SomeKey": "SomeVal"}, а{"test": "test", "somekey": "some value"}, вы можете реструктурировать свою структуру следующим образом:type test_struct struct { Test string `json:"test"` SomeKey string `json:"some-key"` }...и теперь ваш обработчик будет анализировать JSON, используя "some-key", а не" SomeKey " (который вы будете использовать внутри).
Comments