所以我有以下,这似乎令人难以置信的hack,我一直在想,Go有更好的设计库比这,但我找不到一个Go处理JSON数据的POST请求的例子。它们都是来自post。
下面是一个请求示例: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))
}
肯定有更好的办法,对吧?我只是不知道最好的做法是什么。
(围棋在搜索引擎中也被称为Golang,这里提到它是为了让其他人可以找到它。)
你需要从req.Body中读取。ParseForm方法正在从请求中读取数据。主体,然后以标准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))
}
我发现下面的文档示例非常有用。
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响应的很棒的数据。作者解释了结构标签,我不知道。
因为JSON通常看起来不像{"Test": "Test", "SomeKey": "SomeVal"},而是{"Test": "Test", "SomeKey": "some value"},你可以像这样重构你的结构:
type test_struct struct {
Test string `json:"test"`
SomeKey string `json:"some-key"`
}
...现在你的处理程序将使用“some-key”来解析JSON,而不是“SomeKey”(你将在内部使用)。