2015-12-15 168 views
0

在我的应用程序中,我从客户端收到一个json。这个json可以是任何东西,因为用户定义了键和值。在后端,我将它作为字符串存储在数据存储中。将字符串转换为golang中的json,反之亦然?

现在我试图重写MarshalJson/UnmarshalJson函数,以便我从客户端发送/接收的不是字符串,而是json。

我无法弄清楚如何将字符串转换为json。接收到的数据

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

我多么想在数据存储这个上下文字段存储为NOINDEX字符串数据'{'key1':value1, 'key2':value2}' 例子我想给

我的结构

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 }} 
+0

如果数据已经是JSON,并已在弦,你在试图编组或解组? – JimB

+0

现在前端将json转换为字符串,然后在后端接收它。我想改变它,这样前端总是发送一个json,并且在后面我将它作为字符串保存在数据存储区中 – MayK

+1

请提供您要做什么的示例。在解组之前,JSON是一个字符串,所以我不明白“发送一个json”的意思。 – JimB

回答

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

1

我也不知道是什么Y ou想做的事情,但在我知道两种方法将一些接收到的数据转换为json。该数据应为[]byte

首先是让编译器选择界面,并尝试分析以JSON这样:

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

socond如果你知道如何exacly看起来接收到的数据,您可以先定义结构

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我们展示你接收到的数据,可能是他们有一个坏的语法

+0

感谢@Mbded为您的答案,虽然我不知道这是否正是我所需要的。因为我永远不知道接收到的数据是什么样子。 – MayK

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可以更加结构化的,但如果你想使用的数据之前,接受任何一种JSON字符串,然后你要检查一切和转换为正确的类型。

你可以在this playground找到代码。

相关问题