您好,欢迎访问一九零五行业门户网

分享一个Go json 踩坑记录

下面由golang教程栏目给大家分享一个go json 踩坑记录,希望对需要的朋友有所帮助!
json,一种轻量级的资料交换语言,该语言以易于让人阅读的文字为基础,用来传输由属性值或者序列性的值组成的数据对象。现已经被广泛应用,go 当然也提供了完备的支持,通过 encoding/json 便可方便的序列化及反序列化 json 数据。但是也有些关键点需要额外注意下。
go 可使用 json.marshal() 便捷的获取 json 数据,查看该函数对应的 godoc 文档,里面有这么一段话:
string values encode as json strings coerced to valid utf-8, replacing invalid bytes with the unicode replacement rune. so that the json will be safe to embed inside html 3f1c4e4b6b16bbbd69b2ee476dc4f83a tags, the string is encoded using htmlescape, which replaces 0c43feb88fe3846c3aee3dd8022b72eb, &, u+2028, and u+2029 are escaped to \u003c,\u003e, \u0026, \u2028, and \u2029. this replacement can be disabled when using an encoder, by calling setescapehtml(false).
json.marshal() 在进行序列化时,会进行 htmlescape 编码,会将 “f36c3419fe208e1a01c47af887db73c5”, “&”, u+2028, 及 u+2029 转码成 “\u003c”,”\u003e”, “\u0026”, “\u2028”, 和 “\u2029”。这在正常使用时是没有问题的,但如果在对接第三方需要对 json 字符串进行取摘要比对时,如果一方未进行 htmlescape 编码,取出的摘要便会天差地别。上述文档中也给出了解决方法,通过 setescapehtml(false) 来禁用便可。方法如下:
bf := bytes.newbuffer([]byte{})jsonencoder := json.newencoder(bf)jsonencoder.setescapehtml(false)_ = jsonencoder.encode(body)jsonstr := bf.string()
但是这样使用仍然会有些问题,json.encoder.encode() 会在 json 字符串后接一个 换行符,该函数源码如下:
// encode writes the json encoding of v to the stream,// followed by a newline character.//// see the documentation for marshal for details about the// conversion of go values to json.func (enc *encoder) encode(v interface{}) error { if enc.err != nil { return enc.err } e := newencodestate() err := e.marshal(v, encopts{escapehtml: enc.escapehtml}) if err != nil { return err } // terminate each value with a newline. // this makes the output look a little nicer // when debugging, and some kind of space // is required if the encoded value was a number, // so that the reader knows there aren't more // digits coming. e.writebyte('\n') b := e.bytes() if enc.indentprefix != "" || enc.indentvalue != "" { if enc.indentbuf == nil { enc.indentbuf = new(bytes.buffer) } enc.indentbuf.reset() err = indent(enc.indentbuf, b, enc.indentprefix, enc.indentvalue) if err != nil { return err } b = enc.indentbuf.bytes() } if _, err = enc.w.write(b); err != nil { enc.err = err } encodestatepool.put(e) return err}
可以看出,该函数在进行序列化后又写入了一个 \n 字符。如果不需要该字符,则需要额外的将其剔除:
jsonstr := string(bf.bytes()[:bf.bf.len()])
以上就是分享一个go json 踩坑记录的详细内容。
其它类似信息

推荐信息