有没有办法序列化golang http请求对象并持久保存在数据库中

use*_*529 2 serialization http go

我需要在 golang 代码中进行 http 调用。我的服务器代码将创建 http 请求对象并将其放入数据库中。

工作代码将从数据库获取数据,并且应该能够使用持久请求对象进行 http 调用。

我可以通过序列化http请求直接将请求对象持久化到数据库中还是需要在数据库中单独添加method/URL/body?

nob*_*bar 5

没有一个好的方法来序列化http.Request结构本身(请参阅下面的注释),但您可以将请求序列化回 HTTP/1.1 有线格式(也可以反序列化)。Request.Write这可以使用和来完成http.ReadRequest

func captureRequestData(req *http.Request) error {
    var b = &bytes.Buffer{} // holds serialized representation
    var tmp *http.Request
    var err error
    if err = req.Write(b); err != nil { // serialize request to HTTP/1.1 wire format
        return err
    }
    r := bufio.NewReader(b)
    if tmp, err = http.ReadRequest(r); err != nil { // deserialize request
        return err
    }
    *req = *tmp // replace original request structure
    return nil
}
Run Code Online (Sandbox Code Playgroud)

序列化缓冲区的持久性只是保存b. 您可能更愿意保留string表示形式,这涉及一些额外的转换:

s := b.String() // persist this
r := bufio.NewReader(strings.NewReader(s))
Run Code Online (Sandbox Code Playgroud)

至少有几个原因导致您不能仅用json.Marshal()于此目的:

  1. 公共字段Request包括Functions,Marshall 不接受:

    json:不支持的类型:func()(io.ReadCloser,错误)

  2. Request还包含一个私有字段ctx,它会阻止任何通用的反序列化尝试:

    ctx 是客户端或服务器上下文。只能通过使用 WithContext 复制整个请求来修改它。它不被导出,以防止人们错误地使用 Context 并改变同一请求的调用者所持有的上下文。