2016-07-26 51 views
0

我是golang新手,我需要從後面的json字符串中獲取數據。golang轉換json的數組列表結構在glolang

{"data" : ["2016-06-21","2016-06-22","2016-06-25"], "sid" : "ab", "did" : "123"} 

現在我試着用類似

type IntervalData struct { 
    Data json.RawMessage `json:"data"` 
    Did string `json:"did"` 
    Sid string `json:"sid"` 
} 

type IntervalDataList []string 

和JSON解組代碼結構像

r := IntervalData{} 
    json.Unmarshal([]byte(json), &r) 
    log.Printf("Raw Body: %s", r) 

    log.Printf("Raw Date Json: %s", r.Data) 

    blist := IntervalDataList{} 
    json.Unmarshal([]byte(r.Data), &blist) 
    log.Printf("Date List : %s", blist) 

此代碼只能得到SID和JSON字符串沒有數據做了哪些所示作爲空地圖。
什麼可以從上面的json獲取數據的方式。

更新:問題已解決。我檢查了我的輸入json格式爲{"data":"[\"dsadsdsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n\"sdsdadsddad\"]","did":"654646456","sid":"88683627434"},這不是必需的格式。然後我檢查客戶端腳本並根據在線來源進行更改。在消費規範要求 How to JSONize a uint8 slice in Go?

type RequestData struct { 
    Data JSONableSlice `json:"data"` 
    Did string `json:"did"` 
    Sid string `json:"sid"` 
} 
type JSONableSlice []uint8 

func (u JSONableSlice) MarshalJSON() ([]byte, error) { 
    var result string 
    if u == nil { 
     result = "null" 
    } else { 
     result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",") 
    } 
    return []byte(result), nil 
} 

func ApiRequest(w http.ResponseWriter, r *http.Request) { 
    sid := r.Header.Get("sid") 
    deviceID := r.Header.Get("deviceId") 

    body, err := ioutil.ReadAll(r.Body) 
    failOnError(err, "Issue faced during reading post contents") 
    data := RequestData{ 
     Data: body, 
     Sid: sid, 
     Did: dID, 
    } 

    bdata, err := json.Marshal(data) 

    // Some Rabbit MQ Connection code 

    // Rabbit MQ publish code 
    err = ch.Publish(
     "",  // exchange 
     q.Name, // routing key 
     false, // mandatory 
     false, // immediate 
     amqp.Publishing{ 
      DeliveryMode: amqp.Persistent, 
      ContentType: "text/plain", 
      Body:   bdata, 
    }) 
} 

沒有太大的變化,現在

type IntervalData struct { 
     //Data json.RawMessage `json:"data"` 
     Data []byte `json:"data"` 
     Did string `json:"did"` 
     Sid string `json:"sid"` 
    } 
    r := IntervalData{} 
    json.Unmarshal([]byte(json), &r) 
    log.Printf("Raw Body: %s", r) 

    log.Printf("Raw Date Json: %s", r.Data) 

    blist := IntervalDataList{} 
    json.Unmarshal(r.Data, &blist) 
    log.Printf("Date List : %s", blist) 
+0

https://github.com/antonholmquist/jason – pregmatch

+0

也許我錯過了點,但講什麼對已宣佈'IntervalData.Data'爲'[] string'? https://play.golang.org/p/ken-wOlYBf – Havelock

回答

1

在你的示例代碼,你指的是r.data這是一個取消導出場!但是你的IntervalData型號有出口IntervalData.Data字段!這是不一致的。

那麼很可能是你IntervalData包含未導出data場,其中json包忽略,只出口字段封送/取消封送。

只需更改要導出的IntervalData.data字段:IntervalData.Data

見該工作示例:

j := `{"data" : ["2016-06-21","2016-06-22","2016-06-25"], "sid" : "ab", "did" : "123"}` 
r := IntervalData{} 
json.Unmarshal([]byte(j), &r) 
log.Printf("Raw Body: %s", r) 

log.Printf("Raw Data Json: %s", r.Data) 

blist := IntervalDataList{} 
json.Unmarshal([]byte(r.Data), &blist) 
log.Printf("Data List : %s", blist) 

輸出(嘗試在Go Playground):

2009/11/10 23:00:00 Raw Body: {["2016-06-21","2016-06-22","2016-06-25"] 123 ab} 
2009/11/10 23:00:00 Raw Data Json: ["2016-06-21","2016-06-22","2016-06-25"] 
2009/11/10 23:00:00 Data List : [2016-06-21 2016-06-22 2016-06-25] 

還要注意的是,json.RawMessage場和第二拆封是不必要的,你可以定義Data類型爲IntervalDataList,它可以與一個unmarshal一起使用:

Data IntervalDataList `json:"data"` 

和解組:

j := `{"data" : ["2016-06-21","2016-06-22","2016-06-25"], "sid" : "ab", "did" : "123"}` 
r := IntervalData{} 
json.Unmarshal([]byte(j), &r) 
log.Printf("Raw Data Json: %s", r.Data) 

輸出(嘗試這在Go Playground):

2009/11/10 23:00:00 Raw Data Json: [2016-06-21 2016-06-22 2016-06-25] 
+0

哦,這是輸入錯誤,我的代碼只有數據變量而不是數據,但有趣的是代碼工作在你給出的鏈接。經過更多檢查後,我發現我的json變量不是字符串類型,而是[] uint8類型,(它來自消息消費者響應)。 –

+1

@ kuldeep.kamboj'''uint8'與'[] byte'相同,這就是'json.RawMessage'的定義:'type RawMessage [] byte' – icza

0

下面的代碼(或在https://play.golang.org/p/kQRE7xYjrz)解析JSON字符串,並提取/打印出數據字段:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

var data = []byte(`{"data" : ["2016-06-21","2016-06-22","2016-06-25"], "sid" : "ab", "did" : "123"}`) 

type IntervalDataList []string 

type IntervalData struct { 
    Data IntervalDataList `json:"data"` 
    Did string   `json:"did"` 
    Sid string   `json:"sid"` 
} 

func main() { 
    r := &IntervalData{} 
    err := json.Unmarshal(data, r) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Printf("Data: %#v\n", r.Data) 
} 

輸出:

Data: main.IntervalDataList{"2016-06-21", "2016-06-22", "2016-06-25"} 
+0

作爲icza的指針,初始代碼也可以工作,但是主要問題是實際的json與預期的json不同,它會在數據值周圍添加雙引號(以及內部的轉義引號)。 –