Use of golang json Library

Basic introduction to json Library

Objects are passed through byte arrays in the network. In daily front and back-end interaction, they may be used in many forms, such as json, xml, pb, etc. This article mainly introduces the daily usage of json related libraries in golang language

Serializable and Deserialize

Serialization refers to the process of converting an object in memory into a byte array to facilitate transmission in the network. On the contrary, deserialization involves two functions in golang, the location of the package: "encoding/json"

package json

// serialize
func Marshal(v interface{}) ([]byte, error) {
}

// Deserialization
func Unmarshal(data []byte, v interface{}) error {
}

Serialize the incoming object and return a byte array
Deserializing the address of the incoming byte array and the receiving object automatically populates the object

Take an example:

type Student struct {
	Name string
	Age  uint32
}

func main() {
	stu := Student{
		Name: "james",
		Age:  22,
	}

	// marshal
	jsonObj, err := json.Marshal(stu)
	if err != nil {
		panic(err)
	}
	fmt.Printf("jsonObj : %s", jsonObj)

	str := `{"Name":"james","Age":22}`
	var stu2 Student

	// unmarshal
	err = json.Unmarshal([]byte(str), &stu2)
	if err != nil {
		panic(err)
	}
	fmt.Printf("stu2 : %+v\n", stu2)
}

Operation results:

Note: there is a pit here. The field Name of golang must start with uppercase, otherwise the json serialization cannot be completed and the field will be lost. If we lowercase the Name here, the mapping cannot be completed

// Wrong writing. The field must be capitalized and kept public
type Student struct {
	name string
	age  uint32
}

Use of tag

alias

From the above example, we can see that the serialized field Name is the same as the field Name of golang, which is an uppercase Name. Sometimes the field names of json objects agreed at the front and back end are different, so we need to complete the mapping through tag

type Student struct {
	Name string `json:"name"`
	Age  uint32 `json:"age"`
}

At this time, the returned json object will be subject to the alias

The omitempty field can be empty

After using this tag, when a field has no value (i.e. 0 value in golang) during serialization, it will be ignored directly
Look at the differences, which are easy to understand:
Add the qualification field for Age

type Student struct {
	Name string `json:"name"`
	Age  uint32 `json:"age,omitempty"`
}

Set the age to a value of 0 or not initialize

	stu := Student{
		Name: "james",
		Age:  0,
	}

Look at the result comparison after Marshall
Add omitmpty:

marshal not added:

Note: it mainly depends on the protocol requirements

Time related issues

Problem description

When the time you want to enter is in the format of 2006-01-02 15:04:05, you can directly use time There is a problem when receiving time type: cannot parse "00:00:00" "as" T "

type XXXConfig struct {
	StartDate time.Time `json:"start_date"`
	EndDate   time.Time `json:"end_date"`
}

Solution

Because the underlying time types of golang are different, you need to redefine the alias and modify the interface implementation

const (
	YYYYMMDD          = "2006-01-02"
	DefaultTimeFormat = "2006-01-02 15:04:05"
)

// JSONTime is time
type JSONTime time.Time

// UnmarshalJSON for JSON Time
func (t *JSONTime) UnmarshalJSON(data []byte) (err error) {
	now, err := time.ParseInLocation(`"`+DefaultTimeFormat+`"`, string(data), time.Local)
	*t = JSONTime(now)
	return
}

// MarshalJSON for JSON Time
func (t JSONTime) MarshalJSON() ([]byte, error) {
	b := make([]byte, 0, len(DefaultTimeFormat)+2)
	b = append(b, '"')
	b = time.Time(t).AppendFormat(b, DefaultTimeFormat)
	b = append(b, '"')
	return b, nil
}

// String for JSON Time
func (t JSONTime) String() string {
	return time.Time(t).Format(DefaultTimeFormat)
}

At this time, you can change the structure field type to the type defined for yourself

type XXXConfig struct {
	StartDate JSONTime `json:"start_date"`
	EndDate   JSONTime `json:"end_date"`
}

Keywords: Go JSON

Added by jcinsov on Sun, 09 Jan 2022 06:59:15 +0200