go – How to parse http response body to json format in golang?-ThrowExceptions

Exception or error:

I get an reponse body. the format of the body is as below:

  [
    {
       "id":1,
       "name":"111" 
    },
    {
       "id":2,
       "name":"222" 
    }
  ]

I want to parse the body to json struct, my code is as below:

type Info struct {
      Id uint32 `json:id`
      Name string `json:name`
  }

  type Response struct {
      infos []Info
  }

  v := &Response{}
  data, err := ioutil.ReadAll(response.Body)
  if err := json.Unmarshal(data, v); err != nil {
      log.Fatalf("Parse response failed, reason: %v \n", err)
  }

It always give an error:cannot unmarshal array into Go value of type xxx, can someone give a help?

How to solve:

Your data is in the form of array, since starts and ends with squre brackets:

[{"id":1, "name":"111"}, {"id":2, "name":"222"}]

So, you need a slice of Info to unmarshal it ([]Info).
And note you should add double quotes to JSON tags inside backticks like json:"id".

Try this working example:

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

func main() {
    var v []Info
    if err := json.Unmarshal(data, &v); err != nil {
        log.Fatalf("Parse response failed, reason: %v \n", err)
    }
    fmt.Println(v)
}

// Info is ID Name
type Info struct {
    ID   uint32 `json:"id"`
    Name string `json:"name"`
}

// Response is a slice of Info
type Response struct {
    infos []Info
}

var data = []byte(`[
    {
       "id":1,
       "name":"111" 
    },
    {
       "id":2,
       "name":"222" 
    }
  ]`)

Output:

[{1 111} {2 222}]

And if you like to use v := &Response{}, then you need to use &v.infos e.g.: json.Unmarshal(data, &v.infos).

See:
Go by Example: JSON

Docs:

To unmarshal a JSON array into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. As a special case, to unmarshal an empty JSON array into a slice, Unmarshal replaces the slice with a new empty slice.

To unmarshal a JSON array into a Go array, Unmarshal decodes JSON array elements into corresponding Go array elements. If the Go array is smaller than the JSON array, the additional JSON array elements are discarded. If the JSON array is smaller than the Go array, the additional Go array elements are set to zero values.

And try the example on package doc:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var jsonBlob = []byte(`[
    {"Name": "Platypus", "Order": "Monotremata"},
    {"Name": "Quoll",    "Order": "Dasyuromorphia"}
]`)
    type Animal struct {
        Name  string
        Order string
    }
    var animals []Animal
    err := json.Unmarshal(jsonBlob, &animals)
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Printf("%+v", animals)
}

Leave a Reply

Your email address will not be published. Required fields are marked *