使用json.RawMessage解组json以进行结构化

我需要解组可能具有以下格式的json对象:-</ p>

  Format1:

{
“ contactType”:2,
“ value”:“ 0123456789”
}

Format2:

{
“ contactType”:“ MobileNumber” ,
“ value”:“ 0123456789”
}
</ code> </ pre>

我用于解组的结构是:-</ p>

< pre> 类型Contact结构{
ContactType intjson:“ contactType”
值字符串json:“ value”
}
</ code> </ pre>

但这仅适用于格式1。我不想更改ContactType的数据类型,但我也想适应第二种格式。 我听说过json.RawMarshal并尝试使用它。 </ p>

 类型Contact结构{
ContactType int
值字符串json:“ value”
类型json.RawMessage`json:“ contactType”
}

类型StringContact结构{
类型字符串json:“ contactType”
}

类型IntContact结构{
类型intjson:“ contactType”
}
</ code> </ pre>

这完成了编组工作,但是我无法设置ContactType变量,该变量取决于json.RawMessage的类型。 如何为我的结构建模以解决此问题?</ p>
</ div>

展开原文

原文

I need to unmarshal json object which may have the following formats:-

Format1:

    {
    "contactType": 2,
    "value": "0123456789"
    }

Format2:

    {
    "contactType": "MobileNumber",
    "value": "0123456789"
    }

The structure I'm using for unmarshalling is:-

    type Contact struct {
    ContactType int    `json:"contactType"` 
    Value       string `json:"value"`
    }

But this works only for format 1. I dont want to change the datatype of ContactType but I want to accomodate the 2nd format as well. I heard about json.RawMarshal and tried using it.

    type Contact struct {
        ContactType        int
        Value       string          `json:"value"`
        Type json.RawMessage `json:"contactType"
    }

    type StringContact struct {
    Type string `json:"contactType"`
    }

    type IntContact struct {
    Type int `json:"contactType"`
    } 

This gets the unmarshaling done, but I'm unable to set the ContactType variable which depends on the type of json.RawMessage. How do I model my structure so that this problem gets solved?

doushi7314
doushi7314 您可以设置类型界面的联系人类型
大约 4 年之前 回复

1个回答

You will need to do the unmarshalling yourself. There is a very good article that shows how to use the json.RawMessage right and a number of other solutions to this very problem, Like using interfaces, RawMessage, implemention your own unmarshal and decode functions etc.

You will find the article here: JSON decoding in GO by Attila Oláh Note: Attila has made a few errors on his code examples.

I taken the liberty to put together (using some of the code from Attila) a working example using RawMessage to delay the unmarshaling so we can do it on our own version of the Decode func.

Link to GOLANG Playground

package main

import (
    "fmt"
    "encoding/json"
    "io"
)

type Record struct {
    AuthorRaw json.RawMessage `json:"author"`
    Title     string          `json:"title"`
    URL       string          `json:"url"`

    Author Author
}

type Author struct {
    ID    uint64 `json:"id"`
    Email string `json:"email"`
}

func Decode(r io.Reader) (x *Record, err error) {
    x = new(Record)
    if err = json.NewDecoder(r).Decode(x); err != nil {
        return
    }
    if err = json.Unmarshal(x.AuthorRaw, &x.Author); err == nil {
        return
    }
    var s string
    if err = json.Unmarshal(x.AuthorRaw, &s); err == nil {
        x.Author.Email = s
        return
    }
    var n uint64
    if err = json.Unmarshal(x.AuthorRaw, &n); err == nil {
        x.Author.ID = n
    }
    return
}

func main() {

    byt_1 := []byte(`{"author": 2,"title": "some things","url": "https://stackoverflow.com"}`)

    byt_2 := []byte(`{"author": "Mad Scientist","title": "some things","url": "https://stackoverflow.com"}`)

    var dat Record

    if err := json.Unmarshal(byt_1, &dat); err != nil {
            panic(err)
    }
    fmt.Printf("%#s
", dat)

    if err := json.Unmarshal(byt_2, &dat); err != nil {
            panic(err)
    }
    fmt.Printf("%#s
", dat)
}

Hope this helps.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐