May*_*ayK 1 google-app-engine go google-cloud-datastore
在我的应用程序中,我从客户端收到一个 json。这个 json 可以是任何东西,因为用户定义了键和值。在后端,我将它作为字符串存储在数据存储中。
现在我试图覆盖 MarshalJson / UnmarshalJson 函数,以便我从客户端发送/接收的不是字符串而是 json。
我不知道如何在 go 中将字符串转换为 json。
我的结构
type ContextData string
type Iot struct {
Id IotId `json:"id,string" datastore:"-" goon:"id"`
Name string `json:"name"`
Context ContextData `json:"context" datastore:",noindex"` }
Run Code Online (Sandbox Code Playgroud)
接收数据示例
{ 'id' : '',
'name' '',
'context': {
'key1': value1,
'key2': value2 }}
Run Code Online (Sandbox Code Playgroud)
我想如何将此 Context 字段存储在数据存储中作为'{'key1':value1, 'key2':value2}'
我想发送的数据的 noindex 字符串示例
{ 'id' : '',
'name' '',
'context': {
'key1': value1,
'key2': value2 }}
Run Code Online (Sandbox Code Playgroud)
如果您没有结构化数据并且确实需要发送完整的 JSON,那么您可以这样阅读:
// an arbitrary json string
jsonString := "{\"foo\":{\"baz\": [1,2,3]}}"
var jsonMap map[string]interface{}
json.Unmarshal([]byte(jsonString ), &jsonMap)
fmt.Println(jsonMap)
// prints: map[foo:map[baz:[1 2 3]]]
Run Code Online (Sandbox Code Playgroud)
当然,这有一个很大的缺点,因为您不知道每个项目的内容是什么,因此您需要在使用它之前将对象的每个子项转换为正确的类型。
// inner items are of type interface{}
foo := jsonMap["foo"]
// convert foo to the proper type
fooMap := foo.(map[string]interface{})
// now we can use it, but its children are still interface{}
fmt.Println(fooMap["baz"])
Run Code Online (Sandbox Code Playgroud)
如果您发送的 JSON 可以更加结构化,则可以简化此操作,但是如果您想接受任何类型的 JSON 字符串,那么您必须在使用数据之前检查所有内容并转换为正确的类型。
您可以在此 Playground 中找到运行的代码。
如果我正确理解你的问题,你想使用json.RawMessageas Context。
RawMessage 是原始编码的 JSON 对象。它实现了 Marshaler 和 Unmarshaler,可用于延迟 JSON 解码或预先计算 JSON 编码。
RawMessage 只是[]byte,因此您可以将其保存在数据存储中,然后将其作为“预先计算的 JSON”附加到传出消息中。
type Iot struct {
Id int `json:"id"`
Name string `json:"name"`
Context json.RawMessage `json:"context"` // RawMessage here! (not a string)
}
func main() {
in := []byte(`{"id":1,"name":"test","context":{"key1":"value1","key2":2}}`)
var iot Iot
err := json.Unmarshal(in, &iot)
if err != nil {
panic(err)
}
// Context is []byte, so you can keep it as string in DB
fmt.Println("ctx:", string(iot.Context))
// Marshal back to json (as original)
out, _ := json.Marshal(&iot)
fmt.Println(string(out))
}
Run Code Online (Sandbox Code Playgroud)
https://play.golang.org/p/69n0B2PNRv
| 归档时间: |
|
| 查看次数: |
9054 次 |
| 最近记录: |