繁体   English   中英

如何在Golang中将jsonb编码为http响应的一部分

[英]How to encode jsonb as part of an http response in golang

我在通过线路移动JSON时遇到了困难。

在Postgres db中有一个jsonb字段,在通过网络将其作为http响应发送之前,我需要将其添加到结构中。

如果结构的有效负载字段是string ,则封送处理将json转换为"{\\"id\\": \\"3aa5fff0-ad91-41b1-84f0-d97f38e0e0f4\\", \\"user\\": 1 }

如果结构的有效负载字段是json.RawMessage ,则编组将json转换为base64编码字节序列(我想是这样)。

这是我编组并写入http响应流的结构:

type NestJobReturn struct { Status string `json:"status"` Nest json.RawMessage `json:"nest"` }

我建立了这个结构的ret实例并打印出来。 如果我使用%v它将显示字节,而%s显示为正确的,未转义的json字符串:

log("Value of ret.Nest: %v", ret.Nest) // Value of ret.Nest: [123 34 105 ... log("Value of ret.Nest as a string: %s", ret.Nest) // Value of ret.Nest as a string: {"id": "f053...

封送处理和I / O这样完成:

js, _ := json.Marshal(ret) res.Header().Set("Content-Type", "application/json") res.Write(js)

客户端当前收到的整个消息有点像这样:

{"status":"ok","nest":"eyJpZCI6ICJmMD..."}

...但是“ nest”的预期值是数据库中我的jsonb列中的有效json。

有任何想法吗?

您需要将嵌套字段定义为pointer json.RawMessagepointer ,例如

type NestJobReturn struct {
    Status string           `json:"status"`
    Nest   *json.RawMessage `json:"nest"`
}

jsonStr := `{"type": "Object", "desc": "Simple nested object"}`
raw := json.RawMessage(jsonStr)

ret := NestJobReturn {
    Status: "DONE",
    Nest:   &raw,
}

一个工作示例https://play.golang.org/p/Ju7kgbawss

您需要编组指向ret的指针,而不是ret本身

简单地改变
js, _ := json.Marshal(ret)
js, _ := json.Marshal(&ret)

它应该开始工作。
游乐场链接

更好的是,您可以通过使用I Putu Susila的答案或将JSON.RawMessage替换为此稍有调整的版本来构造自己的白痴证明

type RawMessage []byte

// MarshalJSON returns m as the JSON encoding of m.
func (m RawMessage) MarshalJSON() ([]byte, error) {
    return m, nil
}

// UnmarshalJSON sets *m to a copy of data.
func (m *RawMessage) UnmarshalJSON(data []byte) error {
    if m == nil {
        return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
    }
    *m = append((*m)[0:0], data...)
    return nil
}

然后,您的结构将始终正确地编组自己。
游乐场链接

这是该问题在github问题中建议的解决方法(链接由I Putu Susila的评论提供 ),但共识是,即使RawMessage应该这样做,但由于执行该操作,他们现在无法更改它标准库的兼容性保证。 幸运的是,仅仅因为他们无法在标准库中对其进行修复,并不意味着您无法在自己的代码库中对其进行修复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM