开发者

Golang语言如何读取http.Request中body的内容

目录
  • golang读取http.Request中body内容
  • Golang http.Request复用
    • 针对除了Get以外的请求
  • 总结

    Golang读取http.Request中body内容

    不罗嗦了,直接贴代码,不晓得为什么搞这么复杂,是不是因为担心 body 内容一次接受不全,所以搞了个接口来读取其中的内容?

    import (
    	...
    	"io/ioutil"
    	...
    )
    
    ...
    
    func myPost(w http.ResponseWriter, r *http.Request) {
    	s, _ := ioutil.ReadAll(r.Body) //把	body 内容读入字符串 s
    	fmt.Fprintf(w, "%s", s)        //在返回页面中显示内容。
    }
    
    ...编程客栈

    Golang http.Request复用

    针对除了Get以外的请求

    package main
    
    import (
        "net/http"
        "strings"
        )
    
    func main(){
            reader := strings.NewReader("hello")
            req,_ := http.NewRequest("POST","http://www.abc.com",reader)
            client := http.Client{}
            client.Do(req) // 第一次会请求成功
            client.Do(req) // 请求失败
    }

    第二次请求会出错

    http: ContentLength=5 with Body length 0

    原因是第一次请求后req.Body已经读取到结束位置,所以第二次请求时无法再读取body,

    解决方法:

    重新定义一个ReadCloser的实现类替换req.Body

    package reader
    
    import (
        "io"
        "net/http"
        "strings"
        "sync/atomic"
    )
    
    type Repeat struct{
        reader io.ReaderAt
        offset int64
    }
    
    // Read 重写读方法,使每次读取request.Body时能从指定位置读取javascript
    func (p *Repeat) Read(val []byte) (n inePbylWygLWt, err error) {
        n, err = p.reader.ReadAt(val, p.offset)
        atomic.AddInt64(&p.offset, int64(n))
        return
    }
    
    // Reset 重置偏移量
    func (p *Repeat) Reset(){
            atomic.StoreInt64(&p.offset,0)
    }
    
    func (p *Repeat) Close() error {
        // 因为req.Body实现了readcloser接口,所以要实现close方法
        // 但是repeat中的值有可能是只读的,所以这里只是尝试关闭一下。
        if pwww.devze.com.reader != nil {
                ePbylWygLWif rc, ok := p.reader.(io.Closer); ok {
                    return rc.Close()
                }
            }
        return nil
    }
    
    func doPost()  {
        client := http.Client{}
        reader := strings.NewReader("hello")
        req , _ := http.NewRequest("POST","http://www.abc.com",reader)
        req.Body = &Repeat{reader:reader,offset:0}
        client.Do(req)
        // 将偏移量重置为0
        req.Body.(*Repeat).Reset()
        client.Do(req)
    }

    这样就不会报错了,因为也重写了Close()方法,所以同时也解决了request重用时,req.Body自动关闭的问题。

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜