翔云

Just try, don't shy. 最新文章请点击
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

golang 自定义json解析

Posted on 2018-10-17 18:54  翔云123456  阅读(2558)  评论(0编辑  收藏  举报

在实际开发中,经常会遇到需要定制json编解码的情况。
比如,按照指定的格式输出json字符串,
又比如,根据条件决定是否在最后的json字符串中显示或者不显示某些字段。

如果希望自己定义对象的编码和解码方式,需要实现以下两个接口:

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: &

参考

https://golang.org/pkg/encoding/json/

https://blog.csdn.net/tiaotiaoyly/article/details/38942311