json

json tag

  • struct tag : field要大寫開頭,tag各有其功用

+// Field appears in JSON as key "myName" 
+ and the field is omitted from the object if its value is empty,
NickName string `json:"nick_name,omitempty"` 
+//Field appears in JSON as key "Field" (大寫), but the field is skipped if empty.
Address string `json:",omitempty"` 
+// Field is ignored by this package.
A string `json:"-"` 
+// Field appears in JSON as key "-".
B string `json:"-,"` 
+//將輸出轉為string
AgeString int64 `json:"AgeString,string"` 

json Marshel

  • 返回 v 的 JSON 编码

  • supported type See [json/encode]

  • 將struct 轉成 json string

  • Marshel如果字串含有HTML特殊字元會被轉換,如果不想要被轉換需要自己將EscapeHTML設為false

[線上範例](https://go.dev/play/p/GL8zgnPMKpv)
package main

import (
"bytes"
"encoding/json"
"fmt"
)

//field要大寫開頭,tag各有其功用
type UserDetail struct {
Name string `json:"name"`
NickName string `json:"nick_name,omitempty"` // Field appears in JSON as key "myName" and the field is omitted from the object if its value is empty,
Address string `json:",omitempty"` //Field appears in JSON as key "Field" (大寫), but the field is skipped if empty.
A string `json:"-"` // Field is ignored by this package.
B string `json:"-,"` // Field appears in JSON as key "-".
AgeString int64 `json:"AgeString,string"` //將輸出轉為string
Age int64 `json:"Age"`
}
type User struct {
Name string `json:"name"`
}

func main() {
user1 := UserDetail{Name: "123", NickName: "123", Address: "123", A: "A", B: "B", AgeString: 123, Age: 12}
jsonMarshal(user1) //-> json str: {"name":"123","my_name":"123","MyName2":"123","-":"B","int64string":"123","int64":123}

value := make(chan int) //unsupportedTypeEncoder #ref1
jsonMarshal(value) //->Marshal err: json: unsupported type: chan int json str:

user2 := User{Name: "<h1>123</h1>"}
jsonMarshal(user2) //->json str: json str: {"name":"\u003ch1\u003e123\u003c/h1\u003e"}
JsonMarshalEscapeHTMLfalse(user2) ->json str: {"name":"<h1>123</h1>"}
}

//struct to json string
func jsonMarshal(u interface{}) {
ub, err := json.Marshal(u)
if err != nil {
fmt.Println("Marshal err:", err)
}
fmt.Println("json str:", string(ub))
}

func JsonMarshalEscapeHTMLfalse(u interface{}) {
ub, err := JsonEscapeHTMLfalse(u)
if err != nil {
fmt.Println("JsonEscapeHTMLfalse err:", err)
}
fmt.Println("json str:", string(ub))
}

func JsonEscapeHTMLfalse(t interface{}) ([]byte, error) {
buffer := &bytes.Buffer{}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
err := encoder.Encode(t)
return buffer.Bytes(), err
}
o

json.Unmarshal

  • 將json string轉為struct,需了解傳送過來json的結構, 利用type struct 去定義好之後再進行解析

  • 利用 `map[string]interface{}`轉換,但想要取資料解析後比較麻煩,不像是知道結構方便

  • 可以用map取第一層,下一層需reflect,下下層也是...或是利用斷言

  • 僅僅需要將某字串格式化可用

  • 小地方注意:在进行反序列化操作时:第二个参数应该i传地址

+json.Unmarshal([]byte(data), &ns)
-json.Unmarshal([]byte(data), ns)  出錯json: Unmarshal(non-pointer,也會出現毛毛蟲

-json: Unmarshal(non-pointer message.Message)
-反序列化出错出现错误的原因是:在进行反序列化操作时:第二个参数应该i传地址
(ex1):https://go.dev/play/p/kFzxUGvoDNJ
package main

import (
"encoding/json"
"fmt"
)

type User struct {
Name string `json:"name"`
Age int64 `json:"Age"`
Detail Detail `json:"detail"`
}

type Detail struct {
Address string `json:"address"`
}

func main() {
s := `{"name": "123",
"age": 23,
"detail": {
"Address": "abd"
}
}`

var d2 User //定義已知結構
if err := json.Unmarshal([]byte(s), &d2); err != nil {
fmt.Println(err)
}
fmt.Println(d2)
fmt.Println(d2.Detail.Address) //可以很輕鬆拿到內容

}

json.Compact

如果json string是beautify JSON String,json.Compact可以做壓縮。

範例
/func main() {
s := `{"name": "123",
"age": 23,
"detail": {
"Address": "abd"
}
}` //json字串是 beautify JSON String

minfy := compactJSON([]byte(s))
fmt.Println(string(minfy))

}

//json.Compact
func compactJSON(js []byte) []byte {
buf := new(bytes.Buffer)
if err := json.Compact(buf, js); err != nil {
fmt.Println(err)
return nil
}
return buf.Bytes()
}

轉換練習

reference

來源筆記

json.Marshal types

e.g. func or chan refuse to serialize

struct tag 還可以有以下功能

printJson(key string, value interface{})

各个 Go 版本中,标准库 encoding/json 的性能表现 在做出使用第三方序列化库替换标准库的决定前,最好先测试下 json 序列化和反序列化是否是应用的性能瓶颈点

Go 语言中的深拷贝 copier 和 json 的性能

TBD: 編按:雖然本文章說json性能較差 但go1.17實測jaon比較好?why?

Last updated