有人知道在Go中漂亮打印JSON输出的简单方法吗?

我想漂亮地打印json的结果。Marshal,以及格式化现有的JSON字符串,以便更容易阅读。


当前回答

如果你想创建一个命令行工具来漂亮地打印JSON


package main

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


func main(){

    var out bytes.Buffer

    reader := bufio.NewReader(os.Stdin)
    text, _ := reader.ReadString('\n')

    err := json.Indent(&out, []byte(text), "", "  ")
    if err != nil {
      fmt.Println(err)
    }

    fmt.Println(string(out.Bytes()))
}

echo "{\"boo\":\"moo\"}" | go run main.go 

将产生以下输出:

{
  "boo": "moo"
}

请随意构建二进制文件

go build main.go

然后把它放到/usr/local/bin中

其他回答

这是我用的。如果它不能漂亮地打印JSON,它只返回原始字符串。用于打印应该包含JSON的HTTP响应。

import (
    "encoding/json"
    "bytes"
)

func jsonPrettyPrint(in string) string {
    var out bytes.Buffer
    err := json.Indent(&out, []byte(in), "", "\t")
    if err != nil {
        return in
    }
    return out.String()
}

回头看,这是非惯用的围棋。像这样的小助手函数增加了额外的复杂性。一般来说,围棋哲学倾向于包含3条简单的线,而不是1条棘手的线。


正如@robyoder提到的,json。缩进才是正确的选择。我想添加这个小的prettyprint函数:

package main

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

//dont do this, see above edit
func prettyprint(b []byte) ([]byte, error) {
    var out bytes.Buffer
    err := json.Indent(&out, b, "", "  ")
    return out.Bytes(), err
}

func main() {
    b := []byte(`{"hello": "123"}`)
    b, _ = prettyprint(b)
    fmt.Printf("%s", b)
}

https://go-sandbox.com/#/R4LWpkkHIN或http://play.golang.org/p/R4LWpkkHIN

我很沮丧,因为在Go中缺少一种快速、高质量的方法来将JSON编组为彩色字符串,所以我写了自己的编组程序ColorJSON。

有了它,你可以用很少的代码轻松生成如下输出:

package main

import (
    "fmt"
    "encoding/json"

    "github.com/TylerBrock/colorjson"
)

func main() {
    str := `{
      "str": "foo",
      "num": 100,
      "bool": false,
      "null": null,
      "array": ["foo", "bar", "baz"],
      "obj": { "a": 1, "b": 2 }
    }`

    var obj map[string]interface{}
    json.Unmarshal([]byte(str), &obj)

    // Make a custom formatter with indent set
    f := colorjson.NewFormatter()
    f.Indent = 4

    // Marshall the Colorized JSON
    s, _ := f.Marshal(obj)
    fmt.Println(string(s))
}

我现在正在为它写文档,但我很高兴能分享我的解决方案。

responsewriter的另一个例子。

import (
    "encoding/json"
    "net/http"
)

func main() {
    var w http.ResponseWriter

    type About struct {
        ProgName string
        Version string
    }
    goObj := About{ProgName: "demo", Version: "0.0.0"}
    beautifulJsonByte, err := json.MarshalIndent(goObj, "", "  ")
    if err != nil {
        panic(err)
    }
    _, _ = w.Write(beautifulJsonByte)
}

输出

{
  "ProgName": "demo",
  "Version": "0.0.0"
}

如果您想将一个对象转换为JSON,那么接受的答案是非常好的。这个问题还提到了漂亮打印任何JSON字符串,这就是我试图做的。我只是想从POST请求(特别是CSP违反报告)漂亮地记录一些JSON。

要使用MarshalIndent,必须将其解编组到一个对象中。如果你需要,那就去吧,但我不需要。如果你只是需要漂亮地打印一个字节数组,普通缩进是你的朋友。

这是我最后得出的结论:

import (
    "bytes"
    "encoding/json"
    "log"
    "net/http"
)

func HandleCSPViolationRequest(w http.ResponseWriter, req *http.Request) {
    body := App.MustReadBody(req, w)
    if body == nil {
        return
    }

    var prettyJSON bytes.Buffer
    error := json.Indent(&prettyJSON, body, "", "\t")
    if error != nil {
        log.Println("JSON parse error: ", error)
        App.BadRequest(w)
        return
    }

    log.Println("CSP Violation:", string(prettyJSON.Bytes()))
}