[Series] How does Go parse JSON data?

Summary

Recently, I fell into a demand pit and just climbed up. There was a serious problem with the evaluation schedule. The following three pictures are very in line with my mood at that time.

Talk about needs

Estimate Schedule

Start drying

Why is this so? Here's a brief summary:

  • Dock with third party.
  • Docking across teams.
  • For the first time, use Go s as a project.
  • Business processes are scheduled (pits) without being clearly understood.
  • No adjustment schedule (pit) was made after adjustment of demand.

With this experience, you can also chat with others later on about how to evaluate the schedule.

Say nothing more. Enter today's topic.

Today, I want to share with you how to parse JSON data with Go. There are three cases, strong type parsing, weak type parsing, uncertainty in return structure, and so on.

JSON structure

For example, if the interface where the phone belongs is requested, the json data is returned as follows:

{
    "resultcode": "200",
    "reason": "Return Successd!",
    "result": {
        "province": "Zhejiang",
        "city": "Hangzhou",
        "areacode": "0571",
        "zip": "310000",
        "company": "China Mobile",
        "card": ""
    }
}

The idea is as follows:

1. Convert json to struct first.

2. Then json.Unmarshal() will do.

json to struct, handwriting is too troublesome, there are many online tools to use directly, I use this:

https://mholt.github.io/json-to-go/

Strct is generated after json is pasted on the left.

In code:

type MobileInfo struct {
    Resultcode string `json:"resultcode"`
    Reason     string `json:"reason"`
    Result     struct {
        Province string `json:"province"`
        City     string `json:"city"`
        Areacode string `json:"areacode"`
        Zip      string `json:"zip"`
        Company  string `json:"company"`
        Card     string `json:"card"`
    } `json:"result"`
}

func main() {
    jsonStr := `
        {
            "resultcode": "200",
            "reason": "Return Successd!",
            "result": {
                "province": "Zhejiang",
                "city": "Hangzhou",
                "areacode": "0571",
                "zip": "310000",
                "company": "China Mobile",
                "card": ""
            }
        }
    `

    var mobile MobileInfo
    err := json.Unmarshal([]byte(jsonStr), &mobile)
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(mobile.Resultcode)
    fmt.Println(mobile.Reason)
    fmt.Println(mobile.Result.City)
}

Output:

200
Return Successd!
Hangzhou

Perfect resolution.

Now that this is not over, consider these questions:

What if the data type of the json format is not certain?

What if the parameters in the json format data result are not fixed?

The idea is as follows:

Go to github to find the open source class library, haha, I'm using this:

https://github.com/mitchellh/mapstructure

Let's learn together. First, solve the first problem. What if the data type is uncertain?

First, a string type resultcode is defined, but json returns an int type resultcode.

Looking at the document, there is a weak type resolution method, WeakDecode(), so let's try:

type MobileInfo struct {
    Resultcode string `json:"resultcode"`
}

func main() {
    jsonStr := `
        {
            "resultcode": 200
        }
    `

    var result map[string]interface{}
    err := json.Unmarshal([]byte(jsonStr), &result)
    if err != nil {
        fmt.Println(err.Error())
    }

    var mobile MobileInfo
    err = mapstructure.WeakDecode(result, &mobile)
    if err != nil {
        fmt.Println(err.Error())
    }

    fmt.Println(mobile.Resultcode)
}

Output:

200

The first problem has been solved.

To solve the second problem, what if the parameters in the result are not fixed?

Instead of using the example above, look at the official Example (EmbeddedStruct).

type Family struct {
    LastName string
}
type Location struct {
    City string
}
type Person struct {
    Family    `mapstructure:",squash"`
    Location  `mapstructure:",squash"`
    FirstName string
}

func main() {
    input := map[string]interface{}{
        "FirstName": "Mitchell",
        "LastName":  "Hashimoto",
        "City":      "San Francisco",
    }

    var result Person
    err := mapstructure.Decode(input, &result)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FirstName)
    fmt.Println(result.LastName)
    fmt.Println(result.City)
}

Output:

Mitchell
Hashimoto
San Francisco

Using the mapstructure package, the struct tag identity does not write json, but mapstructure.

Explore other things yourself, such as Example (Tags).

go-gin-api series articles

Keywords: Go JSON Mobile github

Added by cdjsjoe on Sat, 04 Jan 2020 17:59:27 +0200