[英]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.RawMessage
的pointer
,例如
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,
}
您需要编组指向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.