问题1:结构体中数字类型与string类型的处理
package main

import (
	"encoding/json"
	"fmt"
)

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

type Person struct {
	Id  int `json:"id,string"`
	Age int `json:"age,string"`
}

func main() {
	p := Person{
		Id:  12,
		Age: 14,
	}
	marshal, _ := json.Marshal(p)
	fmt.Println(string(marshal))
	s := `{"id":"20","age":"20"}`
	_ = json.Unmarshal([]byte(s), &p)
	fmt.Printf("%#v", p)
}

输出:

{"id":"12","age":"14"}
main.Person{Id:20, Age:20}
问题2:数字类型反序列化后变为float64的处理
package main

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

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

func main() {
	m := make(map[string]interface{})
	m["age"] = 1
	marshal, _ := json.Marshal(m)
	fmt.Println(string(marshal))
	s:= `{"age":34}`
	_= json.Unmarshal([]byte(s), &m)
	fmt.Printf("%#v\n",m)
	//⚠️⚠️注意此时的age是float64类型⚠️⚠️
	fmt.Printf("%T\n",m["age"])
	decoder := json.NewDecoder(bytes.NewBuffer([]byte(s)))
	decoder.UseNumber()
	_ = decoder.Decode(&m)
	fmt.Printf("%#v\n",m)
	//打印可以看出此时age是json.Number类型
	fmt.Printf("%T\n",m["age"])
	//⚠️⚠️此处进行断言后调用Int64()方法⚠️⚠️
	i, _ := m["age"].(json.Number).Int64()
	fmt.Printf("%#v\n",i)
	fmt.Printf("%T\n",i)

}

输出:

{"age":1}
map[string]interface {}{"age":34}
float64
map[string]interface {}{"age":"34"}
json.Number
34
int64

问题3:时间格式化的序列化与反序列化的问题

问题原因

package main

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

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

type Person struct {
	Birthday time.Time `json:"birthday"`
}

func main() {
	p := Person{Birthday: time.Now()}
	marshal, _ := json.Marshal(p)
	fmt.Println(string(marshal)) //输出: {"birthday":"2022-02-10T18:05:15.821518+08:00"}

	s := `{"birthday":"2022-02-10 10:00:00"}`
	err := json.Unmarshal([]byte(s), &p)
	//可以看到,对我们习惯对格式化对时间字符串,不是很友好,直接报错了
	fmt.Println(err, p) //输出:parsing time ""2022-02-10 10:00:00"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 10:00:00"" as "T" {0001-01-01 00:00:00 +0000 UTC}

}

输出:

{"birthday":"2022-02-10T18:06:41.992661+08:00"}
parsing time ""2022-02-10 10:00:00"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 10:00:00"" as "T" {0001-01-01 00:00:00 +0000 UTC}

解决方案:

package main

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

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

var format = "2006-01-02 15:04:05"

type Student struct {
	Id       int       `json:"id"`
	Birthday time.Time `json:"birthday"`
}

func (stu *Student) MarshalJSON() ([]byte, error) {
	type TmpStudent Student
	ts := struct {
		Birthday string `json:"birthday"`
		*TmpStudent
	}{Birthday: stu.Birthday.Format(format),
		TmpStudent: (*TmpStudent)(stu)}
	return json.Marshal(ts)
}
func (stu *Student) UnmarshalJSON(data []byte) error {
	type TmpStudent Student
	ts := struct {
		Birthday string `json:"birthday"`
		*TmpStudent
	}{Birthday: stu.Birthday.Format(format),
		TmpStudent: (*TmpStudent)(stu)}
	if err := json.Unmarshal(data, &ts); err != nil {
		return err
	}
	var err error
	stu.Birthday, err = time.ParseInLocation(format, ts.Birthday, time.Local)
	return err

}

func main() {
	s := Student{
		Id:       1,
		Birthday: time.Now(),
	}
	//序列化
	marshal, err := json.Marshal(&s)
	fmt.Println(string(marshal), err)

	//-------------------------------
	//反序列化
	str:=`{"birthday":"2022-02-11 10:58:06","id":9999}`
	_ = json.Unmarshal([]byte(str), &s)
	fmt.Printf("s:%#v\n", s)
}