Как я могу pretty-print JSON с помощью Go?
кто-нибудь знает простой способ pretty-print вывода JSON в Go?
акции http://golang.org/pkg/encoding/json/ пакет, похоже, не включает функциональность для этого (EDIT: это так, см. принятый ответ), и быстрый google не обнаруживает ничего очевидного.
использует Я ищу оба довольно-печать результата json.Marshal
и просто форматирование строки, полной JSON, откуда угодно, поэтому ее легче читать для отладки цели.
8 ответов
под pretty-print я предполагаю, что вы имеете в виду отступ, например
{
"data": 1234
}
, а не
{"data":1234}
самый простой способ сделать это с MarshalIndent
, что позволит вам указать, как вы хотите, чтобы он отступил через
принятый ответ велик, если у вас есть объект, который вы хотите превратить в JSON. В вопросе также упоминается довольно-печать только любой строки JSON, и это то, что я пытался сделать. Я просто хотел довольно-войти в JSON из запроса POST (в частности,отчет о нарушении CSP).
использовать MarshalIndent
, вам придется Unmarshal
это в объект. Если тебе это нужно, действуй, но не я. Если вам просто нужно pretty-print массив байтов, простой Indent
- твой друг.
вот что я закончил:
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()))
}
для лучшего использования памяти, я думаю, это лучше:
var out io.Writer
enc := json.NewEncoder(out)
enc.SetIndent("", " ")
if err := enc.Encode(data); err != nil {
panic(err)
}
редактировать оглядываясь назад, это не идиоматический Go. Небольшие вспомогательные функции, подобные этому, добавляют дополнительный шаг сложности. В общем, философия Go предпочитает включать 3 простые линии над 1 сложной линией.
как упоминал @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/#/R4LWpkkHIN или http://play.golang.org/p/R4LWpkkHIN
Я был разочарован отсутствием быстрого, высококачественного способа маршалировать JSON к раскрашенной строке в Go, поэтому я написал свой собственный Маршаллер под названием ColorJSON.
С его помощью вы можете легко производить вывод, как это, используя очень мало кода:
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))
}
Я пишу документацию для него сейчас, но я был рад поделиться своим решением.
вот что я использую. Если ему не удается распечатать JSON, он просто возвращает исходную строку. Полезно для печати HTTP-ответов, которые должны содержать JSON.
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()
}
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
}
простой с полки довольно принтер в Go. Его можно скомпилировать в двоичный файл через:
go build -o jsonformat jsonformat.go
оно читает от стандартного входного сигнала, пишет К стандартному выходу и позволяет установить вмятие:
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)
}
}
Он позволяет запускать команды bash, такие как:
cat myfile | jsonformat | grep "key"