简体   繁体   English

将嵌套的 JSON 提取为字符串

[英]Extract nested JSON as string

I have a JSON object which I am successfully able to convert to a Go struct.我有一个 JSON 对象,我可以成功地将其转换为 Go 结构体。 However, I have a requirement where I need to parse the nested object in that JSON as a string and I am unable to do it.但是,我有一个要求,我需要将该 JSON 中的嵌套对象解析为字符串,但我无法做到。

Here is the code that works.这是有效的代码。

The Simple JSON that WORKS有效的简单 JSON

{
    "timestamp": "1232159332",
    "duration": 0.5,
}

It converts to the following struct它转换为以下结构

type Beat struct {
    Timestamp   string      `json:"timestamp"`
    Duration    float32     `json:"duration"`
}

func AddBeat(w http.ResponseWriter,  r *http.Request) {
    
    // Step 1 Get JSON parameters:
    b := Beat {}

    decoder := json.NewDecoder(r.Body)
    err := decoder.Decode(&b)
    checkErr(err)

    fmt.Println("Beat: ", b)
}

In the following JSON the nested data object is populated dynamically and its structure can vary.在以下 JSON 中,嵌套data对象是动态填充的,其结构可能会有所不同。 That's why I need to extract it as string and store it in the Database, but Go won't extract it as a string.这就是为什么我需要将其提取为字符串并将其存储在数据库中,但 Go 不会将其提取为字符串。 This Doesn't Work这不起作用

{
    "timestamp": "1232159332",
    "duration": 0.5,
    "data": {
       "key1": "val1",
       "key2": "val2"
    } 
}

Go Code (Doesn't Work) Go 代码(不起作用)

type Beat struct {
    Timestamp   string      `json:"timestamp"`
    Duration    float32     `json:"duration"`
    Data        string      `json:"data"`
}

func AddBeat(w http.ResponseWriter,  r *http.Request) {
    
    // Step 1 Get JSON parameters:
    b := Beat {}

    decoder := json.NewDecoder(r.Body)
    err := decoder.Decode(&b)
    checkErr(err)

    fmt.Println("Beat: ", b)
}

This is the error I get这是我得到的错误

2020/11/25 10:45:24 http: panic serving [::1]:50082: json: cannot unmarshal object into Go struct field Beat.data of type string

Now, the question is how can I extract and decode a nested object in this case data as a string in Go?现在的问题是我怎么能提取和解码在这种情况下,嵌套的对象data作为围棋的字符串?

You probably need to use json.RawMessage :您可能需要使用json.RawMessage

type Beat struct {
    Timestamp   string      `json:"timestamp"`
    Duration    float32     `json:"duration"`
    Data        json.RawMessage      `json:"data"`
}

data := []byte(`{
    "timestamp": "1232159332",
    "duration": 0.5,
    "data": {
       "key1": "val1",
       "key2": "val2"
    } 
}`)
b := Beat{}
err := json.Unmarshal(data, &b)
if err != nil {
    panic(err)
}
fmt.Println(string(b.Data))

https://play.golang.org/p/tHe4kBMSEEJ https://play.golang.org/p/tHe4kBMSEEJ

Or implementing the Unmarshaller interface:或者实现 Unmarshaller 接口:

https://play.golang.org/p/p50GW57yH_U https://play.golang.org/p/p50GW57yH_U

type Beat struct {
    Timestamp   string      `json:"timestamp"`
    Duration    float32     `json:"duration"`
    Data        string      `json:"data"`
}

func (b *Beat) UnmarshalJSON(data []byte) error {
    type beat struct {
        Timestamp   string          `json:"timestamp"`
        Duration    float32         `json:"duration"`
        Data        json.RawMessage `json:"data"`
    }
    bb := &beat{}
    err := json.Unmarshal(data, bb)
    if err != nil {
        return err
    }
    b.Timestamp = bb.Timestamp
    b.Duration = bb.Duration
    b.Data = string(bb.Data)
    return nil
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM