How can I pretty-print JSON using Go?

后端 未结 11 1598
挽巷
挽巷 2020-12-07 08:12

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

The stock http://golang.org/pkg/encoding/json/ package does not seem to include functiona

相关标签:
11条回答
  • 2020-12-07 08:16
    //You can do it with json.MarshalIndent(data, "", "  ")
    
    package main
    
    import(
      "fmt"
      "encoding/json" //Import package
    )
    
    //Create struct
    type Users struct {
        ID   int
        NAME string
    }
    
    //Asign struct
    var user []Users
    func main() {
     //Append data to variable user
     user = append(user, Users{1, "Saturn Rings"})
     //Use json package the blank spaces are for the indent
     data, _ := json.MarshalIndent(user, "", "  ")
     //Print json formatted
     fmt.Println(string(data))
    }
    
    0 讨论(0)
  • 2020-12-07 08:17

    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)
    
    }
    
    0 讨论(0)
  • 2020-12-07 08:18

    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
    }
    
    0 讨论(0)
  • 2020-12-07 08:21

    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.

    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()
    }
    
    0 讨论(0)
  • 2020-12-07 08:23

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

    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.

    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()))
    }
    
    0 讨论(0)
  • 2020-12-07 08:23

    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)
    }
    
    0 讨论(0)
提交回复
热议问题