後端http接口測試常需要打印 JSON 返回,但是默認的json展示形式是緊湊型的,不易閱讀,或許很多人習慣於使用在線格式化工具。但如果能用代碼直接 JSON 美化,爲什麼還要多開一次瀏覽器呢?
struct、map 的 Marsh美化
比如有這樣一個map或者結構體。
u := map[string]interface{}{
"id": 1,
"name": "poloxue",
}
使用GO內置的包 encoding/json。
如果用 json.Marshal 轉化,代碼如下:
uglyBody, err := json.Marshal(u)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", uglyBody)
打印結果:
{"id":1,"name":"poloxue"}
效果並不友好,如果是複雜的 map,結果將非常亂。
可以使用json.MarchalIndent,代碼如下:
body, err := json.MarshalIndent(u, "", "\t")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", body)
t表示縮進效果。最終的結果如下:
{
"id": 1,
"name": "poloxue"
}
看着舒服了很多。
JSON的string如何美化?
如果是一個 JSON 字符串怎麼辦?比如 上面示例中的uglyBody的結果。
方法一
使用 encoding/json 包中 Indent 方法。
代碼如下:
var out bytes.Buffer
err = json.Indent(&out, uglyBody, "", "\t")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", out.String())
結果如下:
{
"id": 1,
"name": "poloxue"
}
方法二
github上面有人實現了一個 JSON pretty的包。
地址在:https://github.com/tidwall/pr...
使用非常簡單,代碼如下:
fmt.Printf("%s\n", pretty.Pretty(uglyBody))
結果如下:
{
"id": 1,
"name": "poloxue"
}
這個庫沒有依賴 encoding/json,純代碼解析字符串。而且還可以做 color 美化。
color美化的示例代碼:
fmt.Printf("%s\n", pretty.Color(uglyBody, pretty.TerminalStyle))
fmt.Printf("%s\n", pretty.Color(pretty.Pretty(uglyBody), pretty.TerminalStyle))
pretty.TerminalStyle表示打印控制檯的着色風格,結果如下:
SO 漂亮!
一個JSON美化小工具
利用上面介紹的這些,開發一個非常簡單的小工具,代碼如下:
package main
import (
"flag"
"fmt"
"github.com/tidwall/pretty"
)
var help bool
var uglyJson string
var indent string
func init() {
flag.BoolVar(&help, "h", false, "show help")
flag.StringVar(&uglyJson, "s", "", "json string")
flag.StringVar(&indent, "i", "\t", "indent string, default tab")
}
func main() {
flag.Parse()
if help {
fmt.Printf("usage:\n\n")
flag.PrintDefaults()
return
}
var Options = &pretty.Options{Width: 80, Prefix: "", Indent: indent, SortKeys: false}
fmt.Printf("%s\n", pretty.Color(pretty.PrettyOptions([]byte(uglyJson), Options), pretty.TerminalStyle))
}
編譯成功之後,就可以用了。比如生成的可執行文件名爲 prettyjson,美化
{"id":1,"name":"poloxue"}。
執行命令如下:
$ ./jsonpretty -s '{"id":1,"name":"poloxue"}'
效果如下:
一些思考
對於 JSON 數據非常大的場景,這種方式可以便於閱讀。如果要快速找到某個字段,通過 grep 可以做到,不過這種情況就無法看到上下文了。想到的解決方案,一種是通過 grep -A -B -C 選項實現上下文展示。還有一種方式,如果這個命令支持指定格式化的最大層級就完美了,不過這是需要二次開發的。