现在我们有一个JSON HTTP请求数据,它将是一个单独的元素
{"data": {"id":1}}
或{"data": [{"id":1}, {"id":2}]}
等元素数组。
由于客户端无法更改实现,我们必须保留并接受此数据结构。
目前我实现的结构如下:
type Request struct {
rawData json.RawMessage `json:"data"`
Data *Data `json:"-"`
DataList []*Data `json:"-"`
}
首先解析"数据"将json.RawMessage属性变为变量req
,首先尝试解析为单个元素,然后尝试解析为数组。
if err := json.Unmarshal(req.rawData, &req.Data); err != nil {
if err := json.Unmarshal(req.RawData, &req.DataList); err != nil {
return errors.New("could not parse data")
} else if len(req.DataList) < 1 {
return errors.New("empty list")
}
}
在这种情况下,稍后当我们想要使用这些数据时,我们可以通过rawData
检查len(req.Datalist) >= 1
是单个元素还是数组。 (或者我可以在解析时设置一些标志来显示结构中的isDataMultiple
)。
除了我正在做的事情之外,是否有任何惯用的方法可以在Go中获得相同的结果?
答案 0 :(得分:1)
我将如何做到这一点:
type Request struct {
RawData json.RawMessage `json:"data" // export field for unmarshal of entire request
DataList []*Data `json:"-"` // always use slice
}
// Is it an array?
if bytes.HasPrefix(bytes.TrimSpace(req.RawData), []byte{'['})) {
if err := json.Unmarshal(req.RawData, &req.DataList); err != nil {
// handle error parsing array
}
} else {
var v Data
if err := json.Unmarshal(req.RawData, &v); err != nil {
// handle error parsing single value
}
req.DataList = []*Data{&v)
}