golang http.request的多个parseBody
嘿,我想像下面一样解析http.resquest两次。当我第一次解析主体时,主体将被关闭。我需要一些帮助/提示处理此问题的最佳方法是什么,我必须创建请求的副本还是有更好的方法golang http.request的多个parseBody,http,go,web,web-development-server,Http,Go,Web,Web Development Server,嘿,我想像下面一样解析http.resquest两次。当我第一次解析主体时,主体将被关闭。我需要一些帮助/提示处理此问题的最佳方法是什么,我必须创建请求的副本还是有更好的方法 func myfunc(w http.ResponseWriter, req *http.Request) { err := parseBody(req, &type1){ ..... } err := parseBody(req, &type2){ ..... } } 感谢您的
func myfunc(w http.ResponseWriter, req *http.Request) {
err := parseBody(req, &type1){
.....
}
err := parseBody(req, &type2){
.....
}
}
感谢您的帮助当您阅读
request.Body
时,您正在从客户端(例如web浏览器)读取流。客户端只发送一次请求。如果要多次解析,请将整个内容读入缓冲区(例如,[]字节
),然后根据需要多次解析。只需注意许多具有大有效负载的并发请求可能会占用内存,因为您将在内存中保存完整的有效负载,至少直到您完全解析它。当您读取request.Body
时,您正在从客户端(例如web浏览器)读取流。客户端只发送一次请求。如果要多次解析,请将整个内容读入缓冲区(例如,[]字节
),然后根据需要多次解析。只需注意许多并发请求可能会占用大量有效负载的内存,因为至少在您完全解析完它之前,您将在内存中保存完整的有效负载。确实,您只能读取一次正文,这是可以的,因为要多次解析正文,您不必多次读取。让我们考虑一个简单的例子:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type RequestData1 struct {
Code string `json:"code"`
Status string `json:"status"`
}
type RequestData2 struct {
Status string `json:"status"`
Message string `json:"message"`
}
func main() {
http.HandleFunc("/post", post)
http.ListenAndServe(":8080", nil)
}
如果我们使用此代码:
func post(w http.ResponseWriter, r *http.Request) {
body1, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
rd1 := RequestData1{}
err = json.Unmarshal(body1, &rd1)
if err != nil {
panic(err)
}
body2, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
rd2 := RequestData2{}
err = json.Unmarshal(body2, &rd2)
if err != nil {
panic(err) // panic!!!
}
fmt.Printf("rd1: %+v \nrd2: %+v", rd1, rd2)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`Look into console.`))
}
我们将有panic:http:panic服务[::1]:54581:JSON输入意外结束
但下一个代码:
func post(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
rd1 := RequestData1{}
err = json.Unmarshal(body, &rd1)
if err != nil {
panic(err)
}
rd2 := RequestData2{}
err = json.Unmarshal(body, &rd2)
if err != nil {
panic(err)
}
fmt.Printf("rd1: %+v \nrd2: %+v", rd1, rd2)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`Look into console.`))
}
一切都好!您可以通过发出请求对其进行测试:
curl -X POST 'http://localhost:8080/post' \
-H 'Content-Type: application/json' -d '{"code":"200", "status": "OK", "message": "200 OK"}'
结果将是:
rd1: {Code:200 Status:OK}
rd2: {Status:OK Message:200 OK}
确实,您只能读取body一次,这没关系,因为要多次解析body,您不必多次读取它。让我们考虑一个简单的例子:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type RequestData1 struct {
Code string `json:"code"`
Status string `json:"status"`
}
type RequestData2 struct {
Status string `json:"status"`
Message string `json:"message"`
}
func main() {
http.HandleFunc("/post", post)
http.ListenAndServe(":8080", nil)
}
如果我们使用此代码:
func post(w http.ResponseWriter, r *http.Request) {
body1, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
rd1 := RequestData1{}
err = json.Unmarshal(body1, &rd1)
if err != nil {
panic(err)
}
body2, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
rd2 := RequestData2{}
err = json.Unmarshal(body2, &rd2)
if err != nil {
panic(err) // panic!!!
}
fmt.Printf("rd1: %+v \nrd2: %+v", rd1, rd2)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`Look into console.`))
}
我们将有panic:http:panic服务[::1]:54581:JSON输入意外结束
但下一个代码:
func post(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
rd1 := RequestData1{}
err = json.Unmarshal(body, &rd1)
if err != nil {
panic(err)
}
rd2 := RequestData2{}
err = json.Unmarshal(body, &rd2)
if err != nil {
panic(err)
}
fmt.Printf("rd1: %+v \nrd2: %+v", rd1, rd2)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`Look into console.`))
}
一切都好!您可以通过发出请求对其进行测试:
curl -X POST 'http://localhost:8080/post' \
-H 'Content-Type: application/json' -d '{"code":"200", "status": "OK", "message": "200 OK"}'
结果将是:
rd1: {Code:200 Status:OK}
rd2: {Status:OK Message:200 OK}
是的,您必须复制正文才能读取它的两份副本。只有这样做,正文才会关闭。此外,您只能从正文中读取一次。是的,您必须复制正文才能读取2份副本。只有这样做,正文才会关闭。你也只能从身体上读一次。@CrimsonKing欢迎随时;)@欢迎随时光临;)