多次读取 Reader

huangapple go评论93阅读模式
英文:

Read multiple time a Reader

问题

我有两个使用相同的http.ResponseWriter和*http.Request的http处理程序,并且像这样读取请求体:

func Method1(w http.ResponseWriter, r *http.Request) {
    var postData database.User
    if err := json.NewDecoder(r.Body).Decode(&postData); err != nil {
        //返回错误
    }
}

func Method2(w http.ResponseWriter, r *http.Request) {
    var postData database.User
    //这个读取操作会产生EOF错误
    if err := json.NewDecoder(r.Body).Decode(&postData); err != nil {
        //返回错误
    }
}

因为我需要保持这两个方法的分离,并且它们都需要读取请求体,所以(如果可能的话)有什么最好的方法可以对请求体进行Seek操作(请求体是ReadCloser,而不是Seeker)?

英文:

I have two http handlers that use the same http.ResponseWriter and *http.Request and read the request body like this:

func Method1 (w http.ResponseWriter, r *http.Request){
    var postData database.User
    if err := json.NewDecoder(r.Body).Decode(&postData); err != nil {
      //return error
    }
}

func Method2 (w http.ResponseWriter, r *http.Request){
    var postData database.User
    //this read gives (of course) EOF error
    if err := json.NewDecoder(r.Body).Decode(&postData); err != nil {
      //return error
    }
}

Because of I need to keep these 2 methods separated, and both of them need to read the request Body, which is the best way (if it's possible) to Seek the request body (which is a ReadCloser, not a Seeker?).

答案1

得分: 4

实际上,感谢miku,我已经发现最好的解决方案是使用TeeReader,以以下方式更改Method1:

func Method1(w http.ResponseWriter, r *http.Request) {
    b := bytes.NewBuffer(make([]byte, 0))
    reader := io.TeeReader(r.Body, b)

    var postData MyStruct
    if err := json.NewDecoder(reader).Decode(&postData); err != nil {
        // 返回一个错误
    }

    r.Body = ioutil.NopCloser(b)
}
英文:

Actually, thanks to miku, I've found out that the best solution is using a TeeReader, changing Method1 in this way

func Method1 (w http.ResponseWriter, r *http.Request){
    b := bytes.NewBuffer(make([]byte, 0))
	reader := io.TeeReader(r.Body, b)

	var postData MyStruct
	if err := json.NewDecoder(reader).Decode(&postData); err != nil {
		//return an error
	}

	r.Body = ioutil.NopCloser(b)
}

huangapple
  • 本文由 发表于 2015年8月8日 02:07:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/31884093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定