Golang的Unmarshal Json无法解析所有子结构。

huangapple go评论78阅读模式
英文:

Golang Unmarshal Json is not parsing all the child structure

问题

我有一个父结构体和两个子结构体ResponseA和ResponseB。我为ParentA结构体编写了"UnmarshalJson"函数。但是ParentB结构体和字符串字段没有解析。我该如何编写自定义的Unmarshal函数,只解析指定的结构体?

type ResponseA struct {
    PageA    int      `json:"pageA"`
    EntriesA []string `json:"entriesA"`
}

type ResponseB struct {
    PageB    int      `json:"pageB"`
    EntriesB []string `json:"entriesB"`
}

type ResponseParent struct {
    ResponseA
    ResponseB
    PageC int `json:"pageC"`
}

func (r *ResponseA) UnmarshalJSON(data []byte) error {
    // 解析ResponseA结构体的逻辑	    
}

func main() {
    jsonStr := `{"pageA": 1, "entriesA": ["classA"], "pageB": 2, "entriesB": ["classC","classD"], "pageC":3}`
    // str := `{"page": 1, "entries": ["classA", "classB"]}`

    var res *ResponseParent
    json.Unmarshal([]byte(jsonStr), &res)
    entriesA := res.EntriesA
    pageA := res.PageA
    entriesB := res.EntriesB
    pageB := res.PageB
    pageC := res.PageC

    fmt.Println("========Response A==========")
    fmt.Println("PageA:", pageA)
    fmt.Println("EntriesA:", entriesA)
    fmt.Println("========Response B==========")
    fmt.Println("PageB:", pageB)
    fmt.Println("EntriesB:", entriesB)
    fmt.Println("PageC:", pageC)
}

输出结果

========Response A==========
PageA: 1
EntriesA: [classA]
========Response B==========
PageB: 0
EntriesB: []
PageC: 0

你可以在UnmarshalJSON函数中编写解析ResponseA结构体的逻辑,然后在main函数中使用json.Unmarshal解析整个JSON字符串。这样,只有ResponseA结构体会被解析,而ResponseB结构体和其他字段将保持为默认值。

英文:

I have one parent structure and two child structures ResponseA and ResponseB. I wrote "UnmarshalJson" function for ParentA structure. The parentB structure and string field are not parsing.
How can I write the custom Unmarshal which only parse the specified structure/

type ResponseA struct {
    PageA    int      `json:"pageA"`
    EntriesA []string `json:"entriesA"`
}

type ResponseB struct {
    PageB    int      `json:"pageB"`
    EntriesB []string `json:"entriesB"`
}

type ResponseParent struct {
    ResponseA
    ResponseB
    PageC int `json:"pageC"`
}

func (r *ResponseA) UnmarshalJSON(data []byte) error {
// UnMarshal ResponseA structure	    
}

func main() {

    jsonStr := `{"pageA": 1, "entriesA": ["classA"], "pageB": 2, "entriesB": 
    ["classC","classD"], "pageC":3}`
 	// str := `{"page": 1, "entries": ["classA", "classB"]}`

    var res *ResponseParent
    json.Unmarshal([]byte(jsonStr), &res)
    entriesA := res.EntriesA
    pageA := res.PageA
    entriesB := res.EntriesB
    pageB := res.PageB
    pageC := res.PageC

    fmt.Println("========Response A==========a")
    fmt.Println("PageA: %v", pageA)
    fmt.Println("EntriesA: %v", entriesA)
    fmt.Println("========Response B==========a")
    fmt.Println("PageB: %v", pageB)
    fmt.Println("EntriesB: %v", entriesB)
    fmt.Println("PageC: %v", pageC)
}

OutPut:

========Response A==========a
PageA: %v 1
EntriesA: %v [classA]
========Response B==========a
PageB: %v 0
EntriesB: %v []
PageC: %v 0

答案1

得分: 3

我测试了一下,我认为这是一个结构性问题,我不知道你是否可以更改你的 JSON 结构,但如果可以的话,你可以尝试只使用两个结构体来实现一个可扩展的结构。

type Response struct {
    Page    int      `json:"page"`
    Entries []string `json:"entries"`
}

type GlobalResponse struct {
    ResponseA Response `json:"pageA"`
    ResponseB Response `json:"pageB"`
    ResponseC Response `json:"pageC"`
}

然后可以这样访问它:

var res *GlobalResponse
json.Unmarshal([]byte(jsonStr), &res)
entriesA := res.ResponseA.Entries
pageA := res.ResponseA.Page
// 对于每个页面都是如此...

最后,JSON 必须更改为以下结构:

{
    "pageA":{
        "page":1,
        "entries":[
            "classA"
        ]
    },
    "pageB":{
        "page":2,
        "entries":[
            "classC",
            "classD"
        ]
    },
    "pageC":{
        "page":3
    }
}

希望对你有所帮助。

英文:

I tested it and I think it's a structural issue, I don't know if you can change your json structure, but if yes you can try to use only 2 structs, to have an evolutive structure

type Response struct {
Page    int      `json:"page"`
Entries []string `json:"entries"`}
}

type GlobalResponse struct {
	ResponseA Response `json:"pageA"`
	ResponseB Response `json:"pageB"`
	ResponseC Response `json:"pageC"`
}

Then acces it this way :

var res *GlobalResponse
json.Unmarshal([]byte(jsonStr), &res)
entriesA := res.ResponseA.Entries
pageA := res.ResponseA.Page
// Etc for each page...

Finally, the json must be changed to that structure

{
    "pageA":{
        "page":1,
        "entries":[
            "classA"
        ]
    },
    "pageB":{
        "page":2,
        "entries":[
            "classC",
        "classD"
        ]
    },
    "pageC":{
        "page":3
    }
}

Hope it helped

huangapple
  • 本文由 发表于 2023年4月6日 16:33:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75947403.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定