我在从POST打印JSON时遇到问题。我使用gorilla/mux
进行路由
r := mux.NewRouter()
r.HandleFunc("/test", Point).Methods("POST")
http.ListenAndServe(":80", r)`
并且在Point
函数中,我具有
func Point(w http.ResponseWriter, r *http.Request) {
var callback Decoder
json.NewDecoder(r.Body).Decode(&callback)
}
但是只有当我知道结构并且想弄清楚如何将整个JSON作为字符串log.Print
时,才能使用此方法。我尝试过
func Point(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
log.Println(r.Form)
}
但是它会打印一个空的地图。请帮忙弄清楚。
假设您正在构建一个接收一些JSON的标准API端点,并且您想对其进行处理,则应通过以下方式进行处理。
编辑:
如使用ioutil.ReadAll()时的注释中所述功能,如本例所示,它将读取在将请求发布到应用程序内存中。检查是个好主意这在生产应用程序中(例如限制有效负载大小)。
1。)创建一个结构,该结构将保存来自GoLang中的API发布请求的数据2.)将您的请求正文转换为字节数组[]byte
3.)Unmarshal
将您的[]byte
转换为先前制作的结构的单个实例。
我在下面放一个例子:
让我们以一个简单的博客文章为例。
JSON对象看起来像这样,并具有slug
,title
和description
{
"slug": "test-slug",
"title": "This is the title",
"body": "This is the body of the page"
}
所以您的结构看起来像这样:
type Page struct {
Slug string `json:"slug"`
Title string `json:"title"`
Body string `json:"body"`
}
byte[]
,然后将该字符串和Unmarshal
放入您的结构实例中。发布请求的数据是请求“正文”。
在Golang中,几乎在所有情况下(除非您使用默认值之外的请求),请求都是一个http.Request对象。这是您通常在常规代码中包含的“ r”,它包含我们POST请求的“正文”。
import (
"encoding/json"
"github.com/go-chi/chi" // you can remove
"github.com/go-chi/render" // you can remove but be sure to remove where it is used as well below.
"io/ioutil"
"net/http"
)
func GiveMeAPage(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("A page"))
}
所以我们在这里要做的就是将io.ReadCloser
转换为http.Request.Body
到[]byte
,因为Unmarshal
函数采用[]byte
类型。我为您在下面对内联发表了评论。
func Create(w http.ResponseWriter, r *http.Request) {
var p Page //Create an instance of our struct
//Read all the data in r.Body from a byte[], convert it to a string, and assign store it in 's'.
s, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err) // This would normally be a normal Error http response but I've put this here so it's easy for you to test.
}
// use the built in Unmarshal function to put the string we got above into the empty page we created at the top. Notice the &p. The & is important, if you don't understand it go and do the 'Tour of Go' again.
err = json.Unmarshal(s, &p)
if err != nil {
panic(err) // This would normally be a normal Error http response but I've put this here so it's easy for you to test.
}
// From here you have a proper Page object which is filled. Do what you want with it.
render.JSON(w, r, p) // This is me using a useful helper function from go-chi which 'Marshals' a struct to a json string and returns it to using the http.ResponseWriter.
}
作为旁注。除非您正在使用JSON流,否则请不要使用
Decoder
来解析JSON。您不在这里,不太可能会一阵子。您可以了解为什么here
如果只需要原始JSON数据而不进行解析,则http.Request.Body
实现io.Reader
,因此您可以从中获取Read
。例如,ioutil.ReadAll
。
类似(未经测试):
func Point(w http.ResponseWriter, r *http.Request) {
data, err := ioutil.ReadAll(r.Body)
// check error
// do whatever you want with the raw data (you can `json.Unmarshal` it too)
}