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

时间:2015-12-15 14:40:42

标签: 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"` }

收到的数据示例

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

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

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

3 个答案:

答案 0 :(得分:4)

如果您没有结构化数据且确实需要发送完整的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]]]

当然,这有一个很大的缺点,因为你不知道每个项目的内容是什么,所以你需要在使用它之前将对象的每个子项强制转换为正确的类型。 / p>

// 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字符串,那么在使用之前你必须检查所有内容并强制转换为正确的类型。数据

您可以在this playground找到代码。

答案 1 :(得分:1)

我也很少知道你想做什么,但在 go 我知道两种方法将一些收到的数据转换为json。此数据应为[]byte类型

首先允许编译器选择接口并尝试以这种方式解析为JSON:

[]byte(`{"monster":[{"basic":0,"fun":11,"count":262}],"m":"18"}`) 
bufferSingleMap   map[string]interface{}
json.Unmarshal(buffer , &bufferSingleMap)

socond如果你知道如何看待收到的数据你可以先定义结构

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)

Imporant是名称价值。应该写一个大写字母(Fun,Count)这是Unmarshal应该是json的标志。 如果您仍然无法解析为JSON,请告诉我们您收到的数据,可能是语法错误

答案 2 :(得分:1)

如果我正确理解您的问题,您希望将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