在Go语言中,encoding/json标准包处理json数据的序列化与反序列化问题。如果想了解序列化可以看这一篇序列化。与编码json的Marshal类似,解析json也提供了Unmarshal方法。对于解析json,也大致分两步,首先定义结构,然后调用Unmarshal方法序列化。

反序列化 Unmarshal()

反序列化源码放在:

Unmarshal

// Unmarshal parses the JSON-encoded data and stores the result
// in the value pointed to by v. If v is nil or not a pointer,
// Unmarshal returns an InvalidUnmarshalError.
//
// Unmarshal uses the inverse of the encodings that
// Marshal uses, allocating maps, slices, and pointers as necessary,
// with the following additional rules:
//
// To unmarshal JSON into a pointer, Unmarshal first handles the case of
// the JSON being the JSON literal null. In that case, Unmarshal sets
// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
// the value pointed at by the pointer. If the pointer is nil, Unmarshal
// allocates a new value for it to point to.
//
// To unmarshal JSON into a value implementing the Unmarshaler interface,
// Unmarshal calls that value's UnmarshalJSON method, including
// when the input is a JSON null.
// Otherwise, if the value implements encoding.TextUnmarshaler
// and the input is a JSON quoted string, Unmarshal calls that value's
// UnmarshalText method with the unquoted form of the string.
//
// To unmarshal JSON into a struct, Unmarshal matches incoming object
// keys to the keys used by Marshal (either the struct field name or its tag),
// preferring an exact match but also accepting a case-insensitive match. By
// default, object keys which don't have a corresponding struct field are
// ignored (see Decoder.DisallowUnknownFields for an alternative).
//
// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:
//
//  bool, for JSON booleans
//  float64, for JSON numbers
//  string, for JSON strings
//  []interface{}, for JSON arrays
//  map[string]interface{}, for JSON objects
//  nil for JSON null
//
// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
// to zero and then appends each element to the slice.
// As a special case, to unmarshal an empty JSON array into a slice,
// Unmarshal replaces the slice with a new empty slice.
//
// To unmarshal a JSON array into a Go array, Unmarshal decodes
// JSON array elements into corresponding Go array elements.
// If the Go array is smaller than the JSON array,
// the additional JSON array elements are discarded.
// If the JSON array is smaller than the Go array,
// the additional Go array elements are set to zero values.
//
// To unmarshal a JSON object into a map, Unmarshal first establishes a map to
// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
// reuses the existing map, keeping existing entries. Unmarshal then stores
// key-value pairs from the JSON object into the map. The map's key type must
// either be a string, an integer, or implement encoding.TextUnmarshaler.
//
// If a JSON value is not appropriate for a given target type,
// or if a JSON number overflows the target type, Unmarshal
// skips that field and completes the unmarshaling as best it can.
// If no more serious errors are encountered, Unmarshal returns
// an UnmarshalTypeError describing the earliest such error. In any
// case, it's not guaranteed that all the remaining fields following
// the problematic one will be unmarshaled into the target object.
//
// The JSON null value unmarshals into an interface, map, pointer, or slice
// by setting that Go value to nil. Because null is often used in JSON to mean
// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
// on the value and produces no error.
//
// When unmarshaling quoted strings, invalid UTF-8 or
// invalid UTF-16 surrogate pairs are not treated as an error.
// Instead, they are replaced by the Unicode replacement
// character U+FFFD.
//
func Unmarshal(data []byte, v interface{}) error {// Check for well-formedness.// Avoids filling out half a data structure// before discovering a JSON syntax error.var d decodeStateerr := checkValid(data, &d.scan)if err != nil {return err}d.init(data)return d.unmarshal(v)
}

从上面的UnMarshal()函数我们可以看到,反序列化是读取字节数组,进而解析为对应的数据结构。

注意:

不是所有的数据都可以编码为 json 格式,只有验证通过的数据结构才能被编码:

json 对象只支持字符串类型的 key;要编码一个 Go map 类型,map 必须是 map[string]T(T是 json 包中支持的任何类型)
channel,复杂类型和函数类型不能被编码
不支持循环数据结构;它将引起序列化进入一个无限循环
指针可以被编码,实际上是对指针指向的值进行编码(或者指针是 nil)

而在Go中,json 与 Go 类型对应如下:

bool 对应 json 的 booleans
float64 对应 json 的 numbers
string 对应 json 的 strings
nil 对应 json 的 null

在解析 json 格式数据时,若以 interface{} 接收数据,需要按照以上规则进行解析。

反序列化成struct

package mainimport ("encoding/json""fmt"
)type Message struct {Address    string  `json:"address"`Age int  `json:23`Name    string `json:"name"`
}var jsonString string = `{"address":"china","age":23,"name":"程序猿编码"
}`
//将json字符串,反序列化成struct
func main() {message := Message{}err := json.Unmarshal([]byte(jsonString), &message)if err != nil{fmt.Println("反序列化失败", err)}fmt.Printf("%+v\n", message)fmt.Println(message)}

输出结果:
定义了1个结构体Message ,结构体Message 的Address 字段tag标签为:json:“address”,表明这个字段在json中的名字对应为address。以此类推

jsonString 我们可以认作为一个json数据,通过json.Unmarshal,我们可以把json中的数据反序列化到了对应结构体。如果定义的字段address为小写,例如:

type Message struct {address    string  `json:"address"`Age int  `json:"age"`Name    string `json:"name"`
}

则会输出:
上面的password并不会被解析赋值json的password,大小写不敏感只是针对公有字段而言。再寻找tag或字段的时候匹配不成功,则会抛弃这个json字段的值:

type Message struct {Age int  `json:"age"`Name    string `json:"name"`
}

这是我们在定义结构体时需要注意的,字段首字母大写。

反序列化成map

直接使用 Unmarshal 把这个数据反序列化,并保存map[string]interface{} 中,要访问这个数据,我们可以使用类型断言:

package main import ("fmt""encoding/json"
)//json字符串,反序列化成map
func main(){str :=  "{\"address\":\"china\",\"age\":23,\"name\":\"minger\"}"var data map[string]interface{}// 使用一个空接口表示可以是任意类型//反序列化err := json.Unmarshal([]byte(str),&data)if err !=nil{fmt.Printf("unmarshal err = %v\n",err)}fmt.Printf("反序列化后 monster = %v\n",data)for k, v := range data {switch vv := v.(type) {case string:fmt.Println(k, "是string", vv)case bool:fmt.Println(k, "是bool", vv)case float64:fmt.Println(k, "是float64", vv)case nil:fmt.Println(k, "是nil", vv)case []interface{}:fmt.Println(k, "是array:")for i, u := range vv {fmt.Println(i, u)}default:fmt.Println(k, "未知数据类型")}}
}

输出结果:
通过这种方式,即使是未知 json 数据结构,我们也可以反序列化,同时可以确保类型安全。

总结

golang和json的大部分数据结构匹配,对于复合结构,go语言可以借助结构体和空接口实现json的数组和对象结构。通过struct tag可以灵活的修改json编码的字段名和输出控制。



喜欢本文的朋友,欢迎关注微信公众号(图一) “程序猿编码” 收看更多精彩文章。扫码二维码(图二);添加本人微信。备注:加群。即可加入程序猿编码交流群

Golang处理JSON(二) 反序列化相关推荐

  1. Golang 处理 Json(二):解码

    golang 编码 json 还比较简单,而解析 json 则非常蛋疼.不像 PHP 一句 json_decode() 就能搞定.之前项目开发中,为了兼容不同客户端的需求,请求的 content-ty ...

  2. 【Groovy】json 字符串反序列化 ( 使用 JsonSlurper 进行 json 字符串反序列化 | 根据 map 集合构造相关类 )

    文章目录 一.使用 JsonSlurper 进行 json 字符串反序列化 二.根据 map 集合构造相关类 三.完整代码示例 一.使用 JsonSlurper 进行 json 字符串反序列化 将如下 ...

  3. rmi 反序列化漏洞_IDEA动态调试(二)——反序列化漏洞(Fastjson)

    一.反序列化的原理及特点 1.什么是反序列化 序列化就是把java类转换成字节流,xml数据.json格式数据等: 反序列化就是把字节流,xml数据.json格式数据转换回java类. 2.反序列化漏 ...

  4. Golang 从 Json 串中快速取出需要的字段

    Golang 从 Json 串中快速取出需要的字段 在 web 编程中很多情况下接口的数据是 json 格式,在我们拿到接口的 json 数据后如何方便地从中提取出需要的字段呢?我们可以自定义一个结构 ...

  5. 再测Golang的JSON库

    2019独角兽企业重金招聘Python工程师标准>>> 写项目一直需要进行序列化,听到了,也看到了很多同学老师对各个golang的json库进行测评.那本人为什么还要继续进行这一次测 ...

  6. golang struct json map 互相转化

    目录 一.Json和struct互换 (1)Json转struct例子 (2)struct转json 二.json和map互转 (1)json转map例子 (2)map转Json例子 三.map和st ...

  7. go 发送http请求; Golang 解析JSON 篇

    https://www.runoob.com/go/go-fmt-sprintf.html go 发送http请求: package mainimport ("io/ioutil" ...

  8. Newtonsoft.Json.dll 反序列化JSON字符串

    上一篇JSON博客<JSON入门级学习小结--JSON数据结构>中已对JSON做了简单介绍,JSON字符串数组数据样式大概是这样子的: 如今因为项目需求(asp.net web网站,前台向 ...

  9. 【Java】用Jackson进行JSON序列化/反序列化操作

    Java类和JSON Speaker类: import java.util.ArrayList; import java.util.Arrays; import java.util.List;publ ...

最新文章

  1. 在NodeJS中操作文件常见的API
  2. Pat乙级 1045 快速排序
  3. 平台积分体系设计方案
  4. CentOS 5 CentOS 6 启动流程及关键步骤
  5. Maven内部版本号插件–用法示例
  6. flash绘制荷花多个图层_Flash鼠绘入门第八课:绘制脱俗荷花
  7. html getelementbyid 修改图片_如何使用HTML、CSS和JS轻松构建桌面应用程序
  8. 用shell查看关键数据
  9. HttpContext.Current.Cache在控制台下不工作
  10. spring boot的学习(1)杂
  11. 正则RegExp对象的用法
  12. 使用Calibre Web打造全功能书库
  13. 【语音数字信号处理】有关幅度谱、相位谱以及利用二者合成频谱
  14. 梯度消失和梯度爆炸原因推导
  15. 数学与计算机学院女生节标语,女生节标语理学院
  16. 安全防护工具之:ClamAV
  17. 第一章 Web MVC简介 —— 跟开涛学SpringMVC 博客分类: 跟开涛学SpringMVC webmvcjavaeespring跟开涛学SpringMVC Web MVC简介 1.1、We
  18. grasp设计模式应用场景_设计模式 GRASP GoF
  19. 金融之期货软件搭建,股票平台搭建,融资融券平台搭建
  20. linux 主流浏览器,各主流浏览器(PC、移动端)userAgent属性信息介绍

热门文章

  1. linux通讯管理机,国电南瑞NSC2200E通讯管理机
  2. 世界因你不同-李开复新书选载
  3. 数说CS|国防科技大学计算机学院是怎样的存在?
  4. 天天静听ASMR-3.2.0——各种声音治疗你的失眠
  5. 数据库知识体系框架图01
  6. 好压haozip 命令帮助
  7. 中国物联网未来发展之路
  8. ASP.NET CORE 2.0 发布到IIS,IIS如何设置环境变量来区分生产环境和测试环境
  9. 嵌入式 Linux 入门(十、Linux 下的 C 编程)
  10. 【习题·搜索】[NOIP2009]靶型数独(搜索+剪枝+位运算优化)