在 golang 中将字符串转换为 json,反之亦然?
convert string to json in golang and vice versa?
在我的应用程序中,我收到来自客户的 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"` }
接收数据示例
{ 'id' : '',
'name' '',
'context': {
'key1': value1,
'key2': value2 }}
我想如何将此上下文字段作为无索引字符串存储在数据存储区中'{'key1':value1, 'key2':value2}'
我要发送的数据示例
{ 'id' : '',
'name' '',
'context': {
'key1': value1,
'key2': value2 }}
我也不太清楚你到底想做什么,但在go中我知道两种将一些接收到的数据转换为json的方法。此数据应为 []byte
类型
首先是允许编译器选择接口并尝试以这种方式解析为 JSON:
[]byte(`{"monster":[{"basic":0,"fun":11,"count":262}],"m":"18"}`)
bufferSingleMap map[string]interface{}
json.Unmarshal(buffer , &bufferSingleMap)
如果您知道接收到的数据的具体外观,您可以先定义结构
type Datas struct{
Monster []struct {
Basic int `json:"basic"`
Fun int `json:"fun"`
Count int `json:"count"`
} `json:"Monster"`
M int `json:"m"`
}
Datas datas;
json.Unmarshal(buffer , &datas)
重要的是名称值。应该写成大写字母(Fun, Count) 这是Unmarshal 的标志,应该是json。
如果您仍然无法解析为 JSON 向我们展示您收到的数据,可能是它们的语法错误
如果你没有结构化数据,而你确实需要发送一个完整的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]]]
当然,这有一个很大的缺点,就是你不知道每个项目的内容是什么,所以你需要在使用之前将对象的每个子对象转换为正确的类型。
// 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"])
如果你发送的 JSON 可以更有条理,你可以简化这个,但是如果你想接受 any 类型的 JSON 字符串,那么你在使用数据之前必须检查所有内容并转换为正确的类型。
您可以在 this playground 中找到有效的代码。
如果我对你的问题的理解正确,你想使用 json.RawMessage
作为 Context
。
RawMessage is a raw encoded JSON object. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.
RawMessage 只是 []byte
,因此您可以将其保存在数据存储中,然后将其作为 "precomputed 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))
}
在我的应用程序中,我收到来自客户的 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"` }
接收数据示例
{ 'id' : '',
'name' '',
'context': {
'key1': value1,
'key2': value2 }}
我想如何将此上下文字段作为无索引字符串存储在数据存储区中'{'key1':value1, 'key2':value2}'
我要发送的数据示例
{ 'id' : '',
'name' '',
'context': {
'key1': value1,
'key2': value2 }}
我也不太清楚你到底想做什么,但在go中我知道两种将一些接收到的数据转换为json的方法。此数据应为 []byte
类型
首先是允许编译器选择接口并尝试以这种方式解析为 JSON:
[]byte(`{"monster":[{"basic":0,"fun":11,"count":262}],"m":"18"}`)
bufferSingleMap map[string]interface{}
json.Unmarshal(buffer , &bufferSingleMap)
如果您知道接收到的数据的具体外观,您可以先定义结构
type Datas struct{
Monster []struct {
Basic int `json:"basic"`
Fun int `json:"fun"`
Count int `json:"count"`
} `json:"Monster"`
M int `json:"m"`
}
Datas datas;
json.Unmarshal(buffer , &datas)
重要的是名称值。应该写成大写字母(Fun, Count) 这是Unmarshal 的标志,应该是json。 如果您仍然无法解析为 JSON 向我们展示您收到的数据,可能是它们的语法错误
如果你没有结构化数据,而你确实需要发送一个完整的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]]]
当然,这有一个很大的缺点,就是你不知道每个项目的内容是什么,所以你需要在使用之前将对象的每个子对象转换为正确的类型。
// 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"])
如果你发送的 JSON 可以更有条理,你可以简化这个,但是如果你想接受 any 类型的 JSON 字符串,那么你在使用数据之前必须检查所有内容并转换为正确的类型。
您可以在 this playground 中找到有效的代码。
如果我对你的问题的理解正确,你想使用 json.RawMessage
作为 Context
。
RawMessage is a raw encoded JSON object. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.
RawMessage 只是 []byte
,因此您可以将其保存在数据存储中,然后将其作为 "precomputed 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))
}