I have a JSON object which I am successfully able to convert to a Go struct. However, I have a requirement where I need to parse the nested object in that JSON as a string and I am unable to do it.
Here is the code that works.
The Simple JSON that WORKS
{
"timestamp": "1232159332",
"duration": 0.5,
}
It converts to the following struct
type Beat struct {
Timestamp string `json:"timestamp"`
Duration float32 `json:"duration"`
}
func AddBeat(w http.ResponseWriter, r *http.Request) {
// Step 1 Get JSON parameters:
b := Beat {}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&b)
checkErr(err)
fmt.Println("Beat: ", b)
}
In the following JSON the nested data
object is populated dynamically and its structure can vary. That's why I need to extract it as string and store it in the Database, but Go won't extract it as a string. This Doesn't Work
{
"timestamp": "1232159332",
"duration": 0.5,
"data": {
"key1": "val1",
"key2": "val2"
}
}
Go Code (Doesn't Work)
type Beat struct {
Timestamp string `json:"timestamp"`
Duration float32 `json:"duration"`
Data string `json:"data"`
}
func AddBeat(w http.ResponseWriter, r *http.Request) {
// Step 1 Get JSON parameters:
b := Beat {}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&b)
checkErr(err)
fmt.Println("Beat: ", b)
}
This is the error I get
2020/11/25 10:45:24 http: panic serving [::1]:50082: json: cannot unmarshal object into Go struct field Beat.data of type string
Now, the question is how can I extract and decode a nested object in this case data
as a string in Go?
You probably need to use json.RawMessage
:
type Beat struct {
Timestamp string `json:"timestamp"`
Duration float32 `json:"duration"`
Data json.RawMessage `json:"data"`
}
data := []byte(`{
"timestamp": "1232159332",
"duration": 0.5,
"data": {
"key1": "val1",
"key2": "val2"
}
}`)
b := Beat{}
err := json.Unmarshal(data, &b)
if err != nil {
panic(err)
}
fmt.Println(string(b.Data))
https://play.golang.org/p/tHe4kBMSEEJ
Or implementing the Unmarshaller interface:
https://play.golang.org/p/p50GW57yH_U
type Beat struct {
Timestamp string `json:"timestamp"`
Duration float32 `json:"duration"`
Data string `json:"data"`
}
func (b *Beat) UnmarshalJSON(data []byte) error {
type beat struct {
Timestamp string `json:"timestamp"`
Duration float32 `json:"duration"`
Data json.RawMessage `json:"data"`
}
bb := &beat{}
err := json.Unmarshal(data, bb)
if err != nil {
return err
}
b.Timestamp = bb.Timestamp
b.Duration = bb.Duration
b.Data = string(bb.Data)
return nil
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.