[json] Go를 사용하여 JSON을 예쁘게 인쇄하려면 어떻게해야합니까?

누구나 Go에서 JSON 출력을 예쁘게 인쇄하는 간단한 방법을 알고 있습니까?

주식 http://golang.org/pkg/encoding/json/ 패키지에는 이것에 대한 기능이 포함되어 있지 않은 것 같으며 (편집 : 허용, 답변 있음) 빠른 Google은 명백한 것을 나타내지 않습니다.

내가 찾고있는 용도는 결과를 예쁘게 인쇄하고 json.Marshal어디서나 JSON으로 가득 찬 문자열을 형식화하는 것이므로 디버그 목적으로 쉽게 읽을 수 있습니다.



답변

예쁜 글씨로, 나는 당신이 그렇게 들여 쓰기를 의미한다고 가정합니다.

{
    "data": 1234
}

오히려

{"data":1234}

이 작업을 수행하는 가장 쉬운 방법 MarshalIndent은을 사용하여 indent인수 를 통해 들여 쓰기를 원하는 방식을 지정할 수 있습니다 . 따라서 json.MarshalIndent(data, "", " ")들여 쓰기를 위해 4 개의 공백을 사용하여 예쁘게 인쇄합니다.


답변

JSON으로 바꾸려는 객체가 있으면 허용되는 답변이 좋습니다. 이 질문에는 JSON 문자열을 예쁘게 인쇄하는 것이 언급되어 있습니다. POST 요청 (특히 CSP 위반 보고서 ) 에서 일부 JSON을 꽤 로깅하고 싶었습니다 .

사용하려면 MarshalIndent, 당신은해야 할 것 Unmarshal객체로 그. 당신이 그것을 원한다면 그것을 위해 가십시오. 바이트 배열을 예쁘게 인쇄 해야하는 경우 평범한 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에서 색상이 지정된 문자열에 JSON을 마샬링하는 빠르고 고품질의 방법이 없기 때문에 좌절했기 때문에 ColorJSON 이라는 내 마샬 러를 작성했습니다 .

그것으로 아주 작은 코드를 사용하여 다음과 같은 출력을 쉽게 생성 할 수 있습니다.

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

지금 문서를 작성하고 있지만 솔루션을 공유하게되어 기뻤습니다.


답변

편집 되돌아 보면, 이것은 관용적이지 않은 바둑입니다. 이와 같은 작은 도우미 기능은 복잡한 단계를 추가합니다. 일반적으로 Go 철학은 1 개의 까다로운 라인에 3 개의 간단한 라인을 포함하는 것을 선호합니다.


@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을 예쁘게 인쇄하지 못하면 원래 문자열을 반환합니다. 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()
}


답변

내 해결책은 다음과 같습니다 .

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
}