Obsługa żądania JSON Post w Go
Więc mam następujące, co wydaje się niesamowicie hacky, i myślałem sobie, że Go ma lepiej zaprojektowane biblioteki niż to, ale nie mogę znaleźć przykład Go obsługi żądania POST danych JSON. Wszystkie one są formą postów.
Oto przykładowe ZAPYTANIE: curl -X POST -d "{\"test\": \"that\"}" http://localhost:8082/test
A oto kod, z wbudowanymi logami:
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))
}
Musi być lepszy sposób, prawda? Nie mogę znaleźć najlepszej praktyki.
(Go jest również znany jako Golang do wyszukiwarek, i wymienione tutaj, aby inni mogli go znaleźć.)
4 answers
Proszę użyć json.Decoder
zamiast 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)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 17:35:10
Musisz czytać z req.Body
. Metoda ParseForm
jest odczytywana z req.Body
, a następnie analizowana w standardowym formacie kodowanym HTTP. To, co chcesz, to odczytać ciało i przetworzyć je w formacie 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))
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-06 08:49:24
Doprowadzałem się do szału z tym problemem. Mój JSON Marshaller i Unmarshaller nie wypełniali mojej struktury Go. Następnie znalazłem rozwiązanie w https://eager.io/blog/go-and-json :
" podobnie jak w przypadku wszystkich struktur w Go, ważne jest, aby pamiętać, że tylko pola z pierwszą wielką literą są widoczne dla zewnętrznych programów, takich jak JSON Marshaller."
Po tym, mój Marshaller i Unmarshaller pracował doskonale!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-15 00:01:24
Poniższy przykład z dokumentów okazał się bardzo pomocny (źródło tutaj).
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)
}
}
Kluczem jest to, że operacja chciała odkodować
type test_struct struct {
Test string
}
... W takim przypadku odrzucilibyśmy const jsonStream
i zamienilibyśmy Message
strukturą na 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)
}
}
Update : dodam jeszcze, że ten post dostarcza również świetnych danych na temat odpowiedzi z JSON. Autor wyjaśnia struct tags
, o czym nie wiedziałem.
Od JSON zazwyczaj nie wygląda jak {"Test": "test", "SomeKey": "SomeVal"}
, ale raczej {"test": "test", "somekey": "some value"}
, możesz zrestrukturyzować swoją strukturę w następujący sposób:
type test_struct struct {
Test string `json:"test"`
SomeKey string `json:"some-key"`
}
...a teraz twój handler będzie analizował JSON używając "some-key" w przeciwieństwie do "SomeKey" (którego będziesz używał wewnętrznie).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-23 14:26:25