Go的json序列化
qingheluo2024-07-19清河洛177
Go的官方encoding/json包实现了常用的json序列化功能包级函数Compact(dst *bytes.Buffer, src []byte) error :将json编码的src中无用的空白字符剔除后写入dstHTMLEscape(dst *bytes.Buffer, src []byte)将json编码的src中的<、>、&、U+2028 和U+2029字符替换为\u003c、\u003e、\u0026、\u2028、\u2029
以便json编码可以安全的嵌入HTML的<script>标签里
因为历史原因,浏览器不支持在<scrip...
Go的官方encoding/json包实现了常用的json序列化功能
包级函数
Compact(dst *bytes.Buffer, src []byte) error :将json编码的src中无用的空白字符剔除后写入dst
HTMLEscape(dst *bytes.Buffer, src []byte)
将json编码的src中的<、>、&、U+2028 和U+2029字符替换为\u003c、\u003e、\u0026、\u2028、\u2029
以便json编码可以安全的嵌入HTML的<script>标签里
因为历史原因,浏览器不支持在<script>标签中使用标准HTML转义,因此必须使用另一种转义方案
Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
将json编码调整缩进之后写入dst
每一个json元素都另起一行开始,以prefix为起始,一或多个indent缩进(数目看嵌套层数)
Marshal(v interface{}) ([]byte, error):返回v的json编码
如果v实现了Marshaler接口切非nil指针,会调用其MarshalJSON方法来生成json编码 否则使用下面的基于类型的默认编码格式: 布尔类型编码为json布尔类型 浮点数、整数和Number类型的值编码为json数字类型,NaN和+/-Inf值将返回一个UndeletedValueError 字符串编码为有效UTF-8编码JSON字符串,用Unicode替换符替换无效字节,然后使用HTMLEscape()对字符串中的特殊字符进行转义 结构体的值编码为json对象,每个字段的编码可以通过字段标记中的"json"键自定义,具体规则 数组和切片类型编码为json数组 []byte编码为base64编码字符串 nil值编码为null,如nil切片、指针、接口等 映射类型的值编码为json对象。键必须是字符串,json对象的键直接使用映射的键 指针类型的值编码为其指向的值的json编码 接口类型的值编码为接口内保持的具体类型的值的json编码 通道、复数、函数类型的值不能编码进json,尝试编码会返回UnsupportedTypeError
MarshalIndent(v interface{}, prefix, indent string) ([]byte, error):类似Marshal但会使用指定前缀和缩进将输出格式化
Unmarshal(data []byte, v interface{}) error:解析json编码的data并将解析结果存入v
JSON的null解析为go的接口、指针、切片时会将它们设为nil,解析为其他类型时,不会造成任何改变,也不会产生错误 接收变量为一个指针 如果json字面值为null将指针设为nil; 否则将json数据解码写入指针指向的值; 如果指针本身是nil,会先申请一个值并使指针指向它 接收变量为一个结构体,会匹配字段标签指定的键名和原始字段名,优先选择精确的匹配,其次进行忽略大小写匹配 接收变量为一个切片中,会首先将切片长度重置为0,然后将每个元素插入重置后的切片中 接收变量为一个数组中,如果接收数组小于JSON数组,丢弃额外的JSON数组元素。如果JSON数组小于接收数组,则其他接收数组元素被设置为零值 接收变量为一个映射中,如果map为nil会分配一个新的map,否则保留现有条目。然后将JSON对象中的键值对存储到map中,接收map的键类型必须是字符串或整数 接收变量为一个接口类型值,函数会将数据解码为如下类型写入接口 Bool 对应JSON布尔类型 float64 对应JSON数字类型 string 对应JSON字符串类型 []interface{} 对应JSON数组 map[string]interface{} 对应JSON对象 nil 对应JSON的null 如果一个JSON值不匹配给出的目标类型,或者一个json数字写入目标类型时溢出,会跳过该字段并尽量完成其余的解码操作并返回结果和一个错误对象,但是不能保证有问题的字段之后的所有剩余字段都将被解封送到目标对象中 当解码字符串时,不合法的utf-8或utf-16不视为错误,而是将非法字符替换为unicode字符U+FFFD 如果JSON编码的数据包含语法错误,将返回SyntaxError
Valid(data []byte) bool :判断data是否是有效的json数据
type Decoder struct {}
解码器,从输入流读取json并解码为Go数据
NewDecoder(r io.Reader) *Decoder:创建一个从r读取json并解码的*Decoder,解码器有自己的缓冲,并可能超前读取部分json数据。 Buffered() io.Reader:返回保存在dec缓存里数据的读取器,该返回值在下次调用Decode方法之前有效 Decode(v interface{}) error:从输入流读取下一个json编码值并解析保存在v中 InputOffset() int64 :返回当前解码器位置的输入流字节偏移量,值为最近返回的标记的结束位置和下一个标记的开始位置 More() bool :报告当前json数组或对象中是否有其他元素 DisallowUnknownFields() :设置dec,在解码器在目标为结构体且输入包含的对象键与目标中任何未忽略的导出字段不匹配时返回错误 UseNumber():设置dec,将一个数字解组到一个interface{}中时作为一个Number而不是一个float64
type Encoder struct {}
编码器,将Go数据编码为json并写入输出流
NewEncoder(w io.Writer) *Encoder:创建一个将编码后的json写入w的*Encoder Encode(v interface{}) error:将v的json编码写入输出流,并会在最后写入一个换行符 SetEscapeHTML(on bool) :指定是否应该在编码json时转义特殊字符 SetIndent(prefix, indent string) :指示将编码格式化
结构体标签规范
在encoding/json包中,对结构体标签中json相关字段进行了规范
1、结构体标签中识别的键名为json 2、对应的值用于控制json中的key名、当字段值为0值时是否解析、解析为字符串 格式为json_key,omitempty,string json_key, 指定转换为json时该字段的key 为空时表示使用原本字段名作为json的key 为"-"时表示在json编码时始终忽略该字段 当需要json的key为"-"时,json_key设置为"-,"(添加一个逗号) omitempty,忽略值为空值的字段(false、0、nil指针、nil接口以及任何空数组、切片、映射或字符串) string,标记一个字段在编码json时应编码为字符串。只适用于字符串、浮点数、整数类型