如何使用 Go 漂亮地打印 JSON?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19038598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I pretty-print JSON using Go?
提问by Brad Peabody
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/包似乎不包含此功能(编辑:它包含,请参阅已接受的答案)并且快速 google 没有发现任何明显的内容。
Uses I'm looking for are both pretty-printing the result of json.Marshaland just formatting a string full of JSON from wherever, so it's easier to read for debug purposes.
我正在寻找的用途是json.Marshal从任何地方漂亮地打印结果和格式化一个充满 JSON 的字符串,因此为了调试目的更容易阅读。
回答by Alexander Bauer
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 indentargument. Thus, json.MarshalIndent(data, "", " ")will pretty-print using four spaces for indentation.
最简单的方法是使用MarshalIndent,它可以让您通过indent参数指定您希望它如何缩进。因此,json.MarshalIndent(data, "", " ")将使用四个空格进行缩进进行漂亮打印。
回答by robyoder
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 Unmarshalthat 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 Indentis your friend.
要使用MarshalIndent,您必须将Unmarshal其放入一个对象中。如果你需要那个,去吧,但我没有。如果你只需要漂亮地打印一个字节数组,plainIndent是你的朋友。
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()))
}
回答by mh-cbon
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)
}
回答by Tyler Brock
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.
我对在 Go 中缺乏快速、高质量的方式将 JSON 编组为彩色字符串感到沮丧,所以我编写了自己的 Marshaller 称为ColorJSON。
With it, you can easily produce output like this using very little code:
有了它,您可以使用很少的代码轻松生成这样的输出:
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))
}
I'm writing the documentation for it now but I was excited to share my solution.
我现在正在为它编写文档,但我很高兴能分享我的解决方案。
回答by jpillora
EditLooking 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 条简单的代码而不是 1 条复杂的代码。
As @robyoder mentioned, json.Indentis the way to go. Thought I'd add this small prettyprintfunction:
正如@robyoder 提到的,这json.Indent是要走的路。以为我会添加这个小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/#/R4LWpkkHINor http://play.golang.org/p/R4LWpkkHIN
https://go-sandbox.com/#/R4LWpkkHIN或http://play.golang.org/p/R4LWpkkHIN
回答by Timmmm
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 shouldcontain 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()
}
回答by Raed Shomali
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
}
回答by Clare Chu
package cube
import (
"encoding/json"
"fmt"
"github.com/magiconair/properties/assert"
"k8s.io/api/rbac/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
)
func TestRole(t *testing.T) {
clusterRoleBind := &v1beta1.ClusterRoleBinding{
ObjectMeta: v1.ObjectMeta{
Name: "serviceaccounts-cluster-admin",
},
RoleRef: v1beta1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "cluster-admin",
},
Subjects: []v1beta1.Subject{{
Kind: "Group",
APIGroup: "rbac.authorization.k8s.io",
Name: "system:serviceaccounts",
},
},
}
b, err := json.MarshalIndent(clusterRoleBind, "", " ")
assert.Equal(t, nil, err)
fmt.Println(string(b))
}


回答by Pawe? Szczur
A simple off the shelf pretty printer in Go. One can compile it to a binary through:
一个简单的现成漂亮的 Go 打印机。可以通过以下方式将其编译为二进制文件:
go build -o jsonformat jsonformat.go
It reads from standard input, writes to standard output and allow to set indentation:
它从标准输入读取,写入标准输出并允许设置缩进:
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
)
func main() {
indent := flag.String("indent", " ", "indentation string/character for formatter")
flag.Parse()
src, err := ioutil.ReadAll(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "problem reading: %s", err)
os.Exit(1)
}
dst := &bytes.Buffer{}
if err := json.Indent(dst, src, "", *indent); err != nil {
fmt.Fprintf(os.Stderr, "problem formatting: %s", err)
os.Exit(1)
}
if _, err = dst.WriteTo(os.Stdout); err != nil {
fmt.Fprintf(os.Stderr, "problem writing: %s", err)
os.Exit(1)
}
}
It allows to run a bash commands like:
它允许运行 bash 命令,例如:
cat myfile | jsonformat | grep "key"
回答by accnameowl
i am sort of new to go, but this is what i gathered up so far:
我有点陌生,但这是我到目前为止收集的内容:
package srf
import (
"bytes"
"encoding/json"
"os"
)
func WriteDataToFileAsJSON(data interface{}, filedir string) (int, error) {
//write data as buffer to json encoder
buffer := new(bytes.Buffer)
encoder := json.NewEncoder(buffer)
encoder.SetIndent("", "\t")
err := encoder.Encode(data)
if err != nil {
return 0, err
}
file, err := os.OpenFile(filedir, os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
return 0, err
}
n, err := file.Write(buffer.Bytes())
if err != nil {
return 0, err
}
return n, nil
}
This is the execution of the function, and just standard
这是函数的执行,只是标准的
b, _ := json.MarshalIndent(SomeType, "", "\t")
Code:
代码:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
minerals "./minerals"
srf "./srf"
)
func main() {
//array of Test struct
var SomeType [10]minerals.Test
//Create 10 units of some random data to write
for a := 0; a < 10; a++ {
SomeType[a] = minerals.Test{
Name: "Rand",
Id: 123,
A: "desc",
Num: 999,
Link: "somelink",
People: []string{"John Doe", "Aby Daby"},
}
}
//writes aditional data to existing file, or creates a new file
n, err := srf.WriteDataToFileAsJSON(SomeType, "test2.json")
if err != nil {
log.Fatal(err)
}
fmt.Println("srf printed ", n, " bytes to ", "test2.json")
//overrides previous file
b, _ := json.MarshalIndent(SomeType, "", "\t")
ioutil.WriteFile("test.json", b, 0644)
}

