如何使用Go进行预打印JSON ?

时间:2022-06-09 02:56:11

Does anyone know of a simple way to pretty-print JSON output in Go?

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

The stock http://golang.org/pkg/encoding/json/ package does not seem to include functionality for this (EDIT: it does, see accepted answer) and a quick google doesn't turn up anything obvious.

股票http://golang.org/pkg/encoding/json/ package似乎没有包含这个的功能(编辑:它有,请参阅已接受的答案),一个快速的谷歌并没有显示任何明显的功能。

Uses I'm looking for are both pretty-printing the result of json.Marshal and just formatting a string full of JSON from wherever, so it's easier to read for debug purposes.

我要查找的用途都是漂亮地打印json结果。对一个满是JSON的字符串进行封送和格式化,这样便于调试。

7 个解决方案

#1


162  

By pretty-print, I assume you mean indented, like so

说到漂亮的印花,我猜你指的是锯齿状的

{
    "data": 1234
}

rather than

而不是

{"data":1234}

The easiest way to do this is with MarshalIndent, which will let you specify how you would like it indented via the indent argument. Thus, json.MarshalIndent(data, "", " ") will pretty-print using four spaces for indentation.

最简单的方法是使用MarshalIndent,它允许您指定如何通过缩进参数对它进行缩进。因此,json。MarshalIndent(data, "", ")将使用四个空格进行缩进。

#2


39  

The accepted answer is great if you have an object you want to turn into JSON. The question also mentions pretty-printing just any JSON string, and that's what I was trying to do. I just wanted to pretty-log some JSON from a POST request (specifically a CSP violation report).

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

To use MarshalIndent, you would have to Unmarshal that into an object. If you need that, go for it, but I didn't. If you just need to pretty-print a byte array, plain Indent is your friend.

要使用MarshalIndent,您必须将其分解为一个对象。如果你需要的话,去争取,但我没有。如果您只需要漂亮地打印字节数组,纯缩进就是您的朋友。

Here's what I ended up with:

这是我最后得出的结论:

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()))
}

#3


24  

For better memory usage, I guess this is better:

为了更好地使用内存,我想这样更好:

var out io.Writer
enc := json.NewEncoder(out)
enc.SetIndent("", "    ")
if err := enc.Encode(data); err != nil {
    panic(err)
}

#4


8  

Edit Looking back, this is non-idiomatic Go. Small helper functions like this add an extra step of complexity. In general, the Go philosophy prefers to include the 3 simple lines over 1 tricky line.

编辑回顾,这是非惯用的。像这样的小助手函数增加了额外的复杂性。一般来说,Go哲学更倾向于把3条简单的线包含在一条复杂的线上。


As @robyoder mentioned, json.Indent is the way to go. Thought I'd add this small prettyprint function:

如@robyoder述,json。缩进是最好的方法。我想添加这个小的漂亮打印功能:

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 or http://play.golang.org/p/R4LWpkkHIN

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

#5


4  

Here's what I use. If it fails to pretty print the JSON it just returns the original string. Useful for printing HTTP responses that should contain JSON.

以下是我使用。如果它不能很好地打印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()
}

#6


3  

I was frustrated by the lack of a fast, high quality way to marshal JSON to a colorized string in Go so I wrote my own Marshaller called ColorJSON.

由于缺乏快速、高质量的方式将JSON编入到一个彩色字符串中,所以我很失望,所以我编写了自己的Marshaller,名为ColorJSON。

With it, you can easily produce output like this using very little code:

有了它,您可以很容易地使用很少的代码生成这样的输出:

如何使用Go进行预打印JSON ?

package main

import (
    "fmt"
    "github.com/TylerBrock/colorjson"
    "encoding/json"
)

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))
}

I'm writing the documentation for it now but I was excited to share my solution.

我现在正在为它编写文档,但是我很高兴与大家分享我的解决方案。

#7


2  

Here is my solution:

这是我的解决方案:

import (
    "bytes"
    "encoding/json"
)

const (
    empty = ""
    tab   = "\t"
)

func PrettyJson(data interface{}) (string, error) {
    buffer := new(bytes.Buffer)
    encoder := json.NewEncoder(buffer)
    encoder.SetIndent(empty, tab)

    err := encoder.Encode(data)
    if err != nil {
       return empty, err
    }
    return buffer.String(), nil
}

#1


162  

By pretty-print, I assume you mean indented, like so

说到漂亮的印花,我猜你指的是锯齿状的

{
    "data": 1234
}

rather than

而不是

{"data":1234}

The easiest way to do this is with MarshalIndent, which will let you specify how you would like it indented via the indent argument. Thus, json.MarshalIndent(data, "", " ") will pretty-print using four spaces for indentation.

最简单的方法是使用MarshalIndent,它允许您指定如何通过缩进参数对它进行缩进。因此,json。MarshalIndent(data, "", ")将使用四个空格进行缩进。

#2


39  

The accepted answer is great if you have an object you want to turn into JSON. The question also mentions pretty-printing just any JSON string, and that's what I was trying to do. I just wanted to pretty-log some JSON from a POST request (specifically a CSP violation report).

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

To use MarshalIndent, you would have to Unmarshal that into an object. If you need that, go for it, but I didn't. If you just need to pretty-print a byte array, plain Indent is your friend.

要使用MarshalIndent,您必须将其分解为一个对象。如果你需要的话,去争取,但我没有。如果您只需要漂亮地打印字节数组,纯缩进就是您的朋友。

Here's what I ended up with:

这是我最后得出的结论:

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()))
}

#3


24  

For better memory usage, I guess this is better:

为了更好地使用内存,我想这样更好:

var out io.Writer
enc := json.NewEncoder(out)
enc.SetIndent("", "    ")
if err := enc.Encode(data); err != nil {
    panic(err)
}

#4


8  

Edit Looking back, this is non-idiomatic Go. Small helper functions like this add an extra step of complexity. In general, the Go philosophy prefers to include the 3 simple lines over 1 tricky line.

编辑回顾,这是非惯用的。像这样的小助手函数增加了额外的复杂性。一般来说,Go哲学更倾向于把3条简单的线包含在一条复杂的线上。


As @robyoder mentioned, json.Indent is the way to go. Thought I'd add this small prettyprint function:

如@robyoder述,json。缩进是最好的方法。我想添加这个小的漂亮打印功能:

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 or http://play.golang.org/p/R4LWpkkHIN

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

#5


4  

Here's what I use. If it fails to pretty print the JSON it just returns the original string. Useful for printing HTTP responses that should contain JSON.

以下是我使用。如果它不能很好地打印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()
}

#6


3  

I was frustrated by the lack of a fast, high quality way to marshal JSON to a colorized string in Go so I wrote my own Marshaller called ColorJSON.

由于缺乏快速、高质量的方式将JSON编入到一个彩色字符串中,所以我很失望,所以我编写了自己的Marshaller,名为ColorJSON。

With it, you can easily produce output like this using very little code:

有了它,您可以很容易地使用很少的代码生成这样的输出:

如何使用Go进行预打印JSON ?

package main

import (
    "fmt"
    "github.com/TylerBrock/colorjson"
    "encoding/json"
)

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))
}

I'm writing the documentation for it now but I was excited to share my solution.

我现在正在为它编写文档,但是我很高兴与大家分享我的解决方案。

#7


2  

Here is my solution:

这是我的解决方案:

import (
    "bytes"
    "encoding/json"
)

const (
    empty = ""
    tab   = "\t"
)

func PrettyJson(data interface{}) (string, error) {
    buffer := new(bytes.Buffer)
    encoder := json.NewEncoder(buffer)
    encoder.SetIndent(empty, tab)

    err := encoder.Encode(data)
    if err != nil {
       return empty, err
    }
    return buffer.String(), nil
}