go json解组选项

试图找到一个简单的解决方案来编组/解组到以下结构中


type Resource struct {

    Data []ResourceData `json:"data"`

}

type ResourceData struct {

    Id string  `json:"id"`

    Type string  `json:"type"`

    Attributes map[string]interface{} `json:"attributes"`

    Relationships map[string]Resource `json:"relationships"`

}

r := Resource{}

json.Unmarshal(body, &r)

如果:


body = `{"data":[{"id":"1","type":"blah"}]}`

但是我也需要它来回应:


body = `{"data":{"id":"1","type":"blah"}}` //notice no slice

我可以做一个单独的类型


type ResourceSingle struct {

    Data ResourceData `json:"data"`

}

但是,这意味着需要复制我附加到资源的所有功能,这是可能的。但是,我需要在执行之前找出要解组的类型,而且当涉及到关系部分时,每个类型都可能包含数据:[]{} 或数据{},所以这个想法不会工作。


或者我可以使用


map[string]*json.RawMessage

//or

type Resource struct {

    Data *json.RawMessage `json:"data"`

}

但是,当以 json 形式存在时,我怎么知道它是一个切片还是一个节点来提供正确的结构以进行解组?


我的最后一招是将 umarshal 转换为 map[string] 接口并使用大量反射测试..但这很冗长。


想法?


慕虎7371278
浏览 147回答 1
1回答

白衣染霜花

有多种方法可以构建它,但最简单的技术归结为实现 ajson.Unmarshaler并检查数据的类型。您可以最低限度地解析 json 字节,通常只是第一个字符,或者您可以尝试解组为每种类型并返回成功的类型。我们将在这里使用后一种技术,并将 ResourceData 插入到切片中,而不管传入数据的格式如何,因此我们始终可以以相同的方式对其进行操作:type Resource struct {    Data []ResourceData}func (r *Resource) UnmarshalJSON(b []byte) error {    // this gives us a temporary location to unmarshal into    m := struct {        DataSlice struct {            Data []ResourceData `json:"data"`        }        DataStruct struct {            Data ResourceData `json:"data"`        }    }{}    // try to unmarshal the data with a slice    err := json.Unmarshal(b, &m.DataSlice)    if err == nil {        log.Println("got slice")        r.Data = m.DataSlice.Data        return nil    } else if err, ok := err.(*json.UnmarshalTypeError); !ok {        // something besides a type error occurred        return err    }    // try to unmarshal the data with a struct    err = json.Unmarshal(b, &m.DataStruct)    if err != nil {        return err    }    log.Println("got struct")    r.Data = append(r.Data, m.DataStruct.Data)    return nil}http://play.golang.org/p/YIPeYv4AfT
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go