print handling golang deserialize json go pretty-print

handling - json to interface golang



¿Cómo puedo imprimir bastante JSON usando Go? (7)

¿Alguien sabe de una manera simple de imprimir bastante la salida JSON en Go?

El paquete http://golang.org/pkg/encoding/json/ stock no parece incluir funcionalidad para esto (EDITAR: lo hace, ver respuesta aceptada) y Google rápido no aparece nada obvio.

Los usos que estoy buscando son los dos: imprimir el resultado de json.Marshal y simplemente formatear una cadena llena de JSON desde cualquier lugar, por lo que es más fácil de leer para depuración.


Esto es lo que uso. Si no puede imprimir bastante el JSON, simplemente devuelve la cadena original. Útil para imprimir respuestas HTTP que deben contener 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() }


La respuesta aceptada es excelente si tiene un objeto que desea convertir en JSON. La pregunta también menciona bastante impresión de cualquier cadena JSON, y eso es lo que estaba tratando de hacer. Solo quería registrar bastante JSON desde una solicitud POST (específicamente un informe de violación de CSP ).

Para usar MarshalIndent , debes Unmarshal eso en un objeto. Si lo necesitas, ve por ello, pero no lo hice. Si solo necesita imprimir bastante una matriz de bytes, su amigo es Indent simple.

Esto es lo que terminé con:

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


Me sentí frustrado por la falta de una manera rápida y de alta calidad de imprimir Marshal JSON en una cadena coloreada en Go, así que escribí mi propio Marshaller llamado ColorJSON .

Con él, puedes producir fácilmente resultados como este usando muy poco código:

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

Estoy escribiendo la documentación ahora, pero estaba emocionado de compartir mi solución.


Para un mejor uso de la memoria, creo que esto es mejor:

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


Por letra bonita, supongo que te refieres a sangría, como tal

{ "data": 1234 }

más bien que

{"data":1234}

La forma más fácil de hacerlo es con MarshalIndent , que le permitirá especificar cómo le gustaría indent través del argumento de indent . Por lo tanto, json.MarshalIndent(data, "", " ") imprimirá con cuatro espacios para la sangría.


Aquí está mi solución :

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 }


Editar Mirando hacia atrás, esto no es idiomático Go. Las pequeñas funciones auxiliares como esta agregan un paso adicional de complejidad. En general, la filosofía Go prefiere incluir las 3 líneas simples sobre 1 línea complicada.

Como @robyoder mencionó, json.Indent es el camino a seguir. Pensé que agregaría esta pequeña función de 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 o http://play.golang.org/p/R4LWpkkHIN