【问题标题】:convert string to json in golang and vice versa?在golang中将字符串转换为json,反之亦然?
【发布时间】:2015-12-15 14:40:42
【问题描述】:

在我的应用程序中,我收到了来自客户端的 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 }}

我想如何将此上下文字段作为 noindex 字符串存储在数据存储中 '{'key1':value1, 'key2':value2}' 我要发送的数据示例

{ 'id' : '',
  'name' '',
  'context': {
           'key1': value1,
           'key2': value2 }}

【问题讨论】:

  • 如果数据已经是json,并且已经在一个字符串中,你要编组或解组什么?
  • 现在前端将 json 转换为字符串,然后我在后端接收它。我想改变它,以便前面总是发送一个 json,而在后面我将它作为字符串保存在数据存储中
  • 请提供一个您正在尝试做的示例。 JSON 是一个字符串,直到你解组它,所以我不明白你所说的“发送一个 json”是什么意思。
  • 我想我不明白你想做什么。但是,如果您正在寻找一种传递本地对象的方法,请尝试 RPC。对我来说,运输一个可以轻松转换为字符串的有效载荷会遇到这么多麻烦,这对我来说毫无意义。
  • @JimB 我不确定我正在尝试做的事情是否毫无价值或正确,但我在我的问题中添加了更多细节

标签: google-app-engine go google-cloud-datastore


【解决方案1】:

如果您没有结构化数据并且确实需要发送完整的 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 中找到代码。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,您想将json.RawMessage 用作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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 感谢@Mbded 的回答,尽管我不确定这是否正是我所需要的。因为我永远不知道收到的数据是什么样子的..
      猜你喜欢
      • 1970-01-01
      • 2022-11-10
      • 2011-05-27
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多