为了账号安全,请及时绑定邮箱和手机立即绑定

在golang中将字符串转换为json,反之亦然?

在golang中将字符串转换为json,反之亦然?

Go
慕妹3242003 2021-11-29 16:19:05
在我的应用程序中,我从客户端收到一个 json。这个 json 可以是任何东西,因为用户定义了键和值。在后端,我将它作为字符串存储在数据存储中。现在我试图覆盖 MarshalJson / UnmarshalJson 函数,以便我从客户端发送/接收的不是字符串而是 json。我不知道如何在 go 中将字符串转换为 json。我的结构type ContextData stringtype 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}' 我想发送的数据的 noindex 字符串示例{ 'id' : '',  'name' '',  'context': {           'key1': value1,           'key2': value2 }}
查看完整描述

3 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

如果您没有结构化数据并且确实需要发送完整的 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 可以更加结构化,则可以简化此操作,但是如果您想接受任何类型的 JSON 字符串,那么您必须在使用数据之前检查所有内容并转换为正确的类型。


您可以在此 Playground 中找到运行的代码。


查看完整回答
反对 回复 2021-11-29
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

如果我正确理解您的问题,您想使用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))

}

https://play.golang.org/p/69n0B2PNRv


查看完整回答
反对 回复 2021-11-29
?
大话西游666

TA贡献1817条经验 获得超14个赞

我也不知道你到底想做什么,但是在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 向我们展示您收到的数据,可能是它们的语法错误


查看完整回答
反对 回复 2021-11-29
  • 3 回答
  • 0 关注
  • 209 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信