2015-12-15 163 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找到代碼。

相關問題