Quelqu'un connaît-il un moyen simple d'imprimer une sortie JSON dans Go?
Le package stock http://golang.org/pkg/encoding/json/ ne semble pas inclure de fonctionnalité pour cela (EDIT: c'est le cas, voir la réponse acceptée) et un rapide google ne révèle rien d'évident.
Les utilisations que je recherche sont à la fois l'impression du résultat json.Marshal
et le formatage d'une chaîne pleine de JSON de n'importe où, ce qui facilite la lecture à des fins de débogage.
json
go
pretty-print
Brad Peabody
la source
la source
{name: "value"}
ça ne va pas, malgré que la plupart des interpréteurs Javascript l'utilisent . Seul{"name": "value"}
fonctionnera avec les fonctions de la bibliothèque Go JSON.Réponses:
Par joli imprimé, je suppose que vous voulez dire en retrait, comme ça
{ "data": 1234 }
plutôt que
{"data":1234}
Le moyen le plus simple de le faire est avec
MarshalIndent
, qui vous permettra de spécifier comment vous souhaitez le mettre en retrait via l'indent
argument. Ainsi,json.MarshalIndent(data, "", " ")
joliment imprimer en utilisant quatre espaces pour l'indentation.la source
json.MarshalIndent(data, "", "\t")
si vous voulez des onglets.json.MarshalIndent(data, "", "🐱")
si vous voulez des chats. désoléjson.MarshalIndent(data, "", "\t🐱")
si vous voulez ... chats tabby ... désoléLa réponse acceptée est excellente si vous avez un objet que vous souhaitez transformer en JSON. La question mentionne également la jolie impression de n'importe quelle chaîne JSON, et c'est ce que j'essayais de faire. Je voulais juste enregistrer un peu de JSON à partir d'une requête POST (en particulier un rapport de violation CSP ).
Pour l'utiliser
MarshalIndent
, vous auriez àUnmarshal
cela dans un objet. Si vous en avez besoin, allez-y, mais je ne l'ai pas fait. Si vous avez juste besoin d'imprimer un tableau d'octets, plainIndent
est votre ami.Voici ce que j'ai fini avec:
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())) }
la source
Pour une meilleure utilisation de la mémoire, je suppose que c'est mieux:
var out io.Writer enc := json.NewEncoder(out) enc.SetIndent("", " ") if err := enc.Encode(data); err != nil { panic(err) }
la source
SetIndent
vous été ajouté récemment? C'est essentiellement inconnu de la plupart.SetIndent
(nommé à l'origineIndent
) a apparemment été ajouté en mars 2016 et publié dans Go 1.7, soit environ 3 ans après que cette question ait été posée à l'origine: github.com/golang/go/commit/… github.com/golang/go/commit/ …J'étais frustré par le manque d'un moyen rapide et de haute qualité de rassembler JSON en une chaîne colorisée dans Go, alors j'ai écrit mon propre Marshaller appelé ColorJSON .
Avec lui, vous pouvez facilement produire une sortie comme celle-ci en utilisant très peu de 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)) }
J'écris la documentation pour cela maintenant mais j'étais ravi de partager ma solution.
la source
Edit Avec le recul, c'est Go non idiomatique. De petites fonctions d'aide comme celle-ci ajoutent une étape supplémentaire de complexité. En général, la philosophie Go préfère inclure les 3 lignes simples sur 1 ligne délicate.
Comme @robyoder l'a mentionné,
json.Indent
c'est la voie à suivre. Je pensais ajouter cette petiteprettyprint
fonction: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 ou http://play.golang.org/p/R4LWpkkHIN
la source
Voici ce que j'utilise. S'il ne parvient pas à imprimer correctement le JSON, il renvoie simplement la chaîne d'origine. Utile pour imprimer des réponses HTTP qui doivent contenir 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 source
Voici ma 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 }
la source
Une jolie imprimante simple prête à l'emploi dans Go. On peut le compiler en binaire via:
go build -o jsonformat jsonformat.go
Il lit à partir de l'entrée standard, écrit sur la sortie standard et permet de définir l'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) } }
Il permet d'exécuter des commandes bash comme:
cat myfile | jsonformat | grep "key"
la source
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)) }
la source
Je suis un peu nouveau, mais c'est ce que j'ai compris jusqu'à présent:
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 }
C'est l'exécution de la fonction, et juste 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) }
la source
//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)) }
la source