golangカスタムjson解析

1748 ワード

実際の開発では,json符号化をカスタマイズする必要がある場合がしばしばある.たとえば、指定したフォーマットでjson文字列を出力したり、条件に応じて最後のjson文字列にフィールドを表示するか、表示しないかを決定したりします.
オブジェクトの符号化と復号化方法を自分で定義するには、次の2つのインタフェースが必要です.
type Marshaler interface {
    MarshalJSON() ([]byte, error)
}
type Unmarshaler interface {
    UnmarshalJSON([]byte) error
}

オブジェクトがインタフェースを実装すると,符号化時にカスタムメソッドを自動的に呼び出して符号化する.
次の例では、カスタムコーディング方法を示す.符号化時にmapを文字列配列に変換します.復号時に文字列配列をmapに変換します.
package main

import (
	"encoding/json"
	"fmt"
)

type Bird struct {
	A	map[string]string	`json:"a"`
}

func (bd *Bird) MarshalJSON() ([]byte, error) {
	l := []string{}
	for _,v := range bd.A {
		l = append(l,v)
	}

	return json.Marshal(l)
}

func (bd *Bird) UnmarshalJSON(b []byte) error {
	l := []string{}
	err := json.Unmarshal(b, &l)
	if err != nil {
		return err
	}

	for i,v := range l {
		k := fmt.Sprintf("%d", i)
		bd.A[k] = v
	}	

	return nil
}


func main() {

	m := map[string]string{"1": "110", "2":"120", "3":"119"}
	xiQue := &Bird{A:m}

	xJson, err := json.Marshal(xiQue)
	if err != nil {
		fmt.Println("json.Marshal failed:", err)
	}

	fmt.Println("xJson:", string(xJson))

	b := `["apple", "orange", "banana"]`	
	
	baoXiNiao := &Bird{A:map[string]string{}}
	err = json.Unmarshal([]byte(b), baoXiNiao)
	if err != nil {
		fmt.Println("json.Unmarshal failed:", err)
	}

	fmt.Println("baoXiNiao:", baoXiNiao)
}


output:
xJson: [“110”,“120”,“119”] baoXiNiao: &{map[0:apple 1:orange 2:banana]}
リファレンス
https://golang.org/pkg/encoding/json/
https://blog.csdn.net/tiaotiaoyly/article/details/38942311