json.Unmarshal nested object into string or []byte

余生颓废 提交于 2019-12-01 15:03:56

I think what you are looking for is the RawMessage type in the encoding/json package.

The documentation states:

type RawMessage []byte

RawMessage is a raw encoded JSON object. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.

Here is a working example of using RawMessage:

package main

import (
    "encoding/json"
    "fmt"
)

var jsonStr = []byte(`{
    "id"  : 15,
    "foo" : { "foo": 123, "bar": "baz" }
}`)

type Bar struct {
    Id  int64           `json:"id"`
    Foo json.RawMessage `json:"foo"`
}

func main() {
    var bar Bar

    err := json.Unmarshal(jsonStr, &bar)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", bar)
}

Output:

{Id:15 Foo:[123 32 34 102 111 111 34 58 32 49 50 51 44 32 34 98 97 114 34 58 32 34 98 97 122 34 32 125]}

Playground

gigatropolis

The Foo type is a map[string]string so define Foo correctly:

type Bar struct {
    id int64
    Foo map[string]string
}

Think that would work better

Defining a type which implements the Unmarshaler interface gives you access to the []byte's being parsed.

type Prefs []byte

func (p *Prefs) UnmarshalJSON(b []byte) error {
    *p = make(Prefs, len(b))
    copy(*p, b)
    return nil
}

playground demo

After a bit of tinkering I've found that in your playground demo the biggest problem is the typecasting of the json to a []byte. To see what I mean by that, take a look a this playground: http://play.golang.org/p/M0706KCZbh

If you run it, you'll notice the []byte between the typecast slice and the marshaled slice differ around the point of the 'Prefs' variable.

json marshaled from struct

[123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 34 101 121 65 105 90...

typecast []byte

[123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 123 34 102 111 111 34...

I've removed white space to try and make it line up as much as possible. The main takeaway from this is that typecasting does not produce the same results as running the data through the json.Marshal method and to make this work you would need a custom type to handle the unmarshaling of what the json package does not recognize.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!