Convertir une chaîne JSON en sortie JSON Pretty Print à l'aide de Jackson

165

Voici la chaîne JSON que j'ai:

{"attributes":[{"nm":"ACCOUNT","lv":[{"v":{"Id":null,"State":null},"vt":"java.util.Map","cn":1}],"vt":"java.util.Map","status":"SUCCESS","lmd":13585},{"nm":"PROFILE","lv":[{"v":{"Party":null,"Ads":null},"vt":"java.util.Map","cn":2}],"vt":"java.util.Map","status":"SUCCESS","lmd":41962}]}

Je dois convertir le JSON ci-dessus Stringen sortie JSON Pretty Print (en utilisant Jackson), comme ci-dessous:

{
    "attributes": [
        {
            "nm": "ACCOUNT",
            "lv": [
                {
                    "v": {
                        "Id": null,
                        "State": null
                    },
                    "vt": "java.util.Map",
                    "cn": 1
                }
            ],
            "vt": "java.util.Map",
            "status": "SUCCESS",
            "lmd": 13585
        },
        {
            "nm": "PROFILE
            "lv": [
                {
                    "v": {
                        "Party": null,
                        "Ads": null
                    },
                    "vt": "java.util.Map",
                    "cn": 2
                }
            ],
            "vt": "java.util.Map",
            "status": "SUCCESS",
            "lmd": 41962
        }
    ]
}

Quelqu'un peut-il me donner un exemple basé sur mon exemple ci-dessus? Comment réaliser ce scénario? Je sais qu'il existe de nombreux exemples, mais je ne suis pas en mesure de les comprendre correctement. Toute aide sera appréciée avec un exemple simple.

Actualisé:

Voici le code que j'utilise:

ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.defaultPrettyPrintingWriter().writeValueAsString(jsonString));

Mais cela ne fonctionne pas avec la façon dont j'avais besoin de la sortie comme mentionné ci-dessus.

Voici le POJO que j'utilise pour le JSON ci-dessus:

public class UrlInfo implements Serializable {

    private List<Attributes> attribute;

}

class Attributes {

    private String nm;
    private List<ValueList> lv;
    private String vt;
    private String status;
    private String lmd;

}


class ValueList {
    private String vt;
    private String cn;
    private List<String> v;
}

Quelqu'un peut-il me dire si j'ai le bon POJO pour le JSON ou non?

Actualisé:

String result = restTemplate.getForObject(url.toString(), String.class);

ObjectMapper mapper = new ObjectMapper();
Object json = mapper.readValue(result, Object.class);

String indented = mapper.defaultPrettyPrintingWriter().writeValueAsString(json);

System.out.println(indented);//This print statement show correct way I need

model.addAttribute("response", (indented));

La ligne ci-dessous imprime quelque chose comme ceci:

System.out.println(indented);


{
  "attributes" : [ {
    "nm" : "ACCOUNT",
    "error" : "null SYS00019CancellationException in CoreImpl fetchAttributes\n java.util.concurrent.CancellationException\n\tat java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat java.util.concurrent.FutureTask.",
    "status" : "ERROR"
  } ]
}

c'est la manière dont j'avais besoin d'être montré. Mais quand je l'ajoute au modèle comme ceci:

model.addAttribute("response", (indented));

Et puis le montre dans une page jsp resultform comme ci-dessous:

    <fieldset>
        <legend>Response:</legend>
            <strong>${response}</strong><br />

    </fieldset>

J'obtiens quelque chose comme ça:

{ "attributes" : [ { "nm" : "ACCOUNT", "error" : "null    
SYS00019CancellationException in CoreImpl fetchAttributes\n 
java.util.concurrent.CancellationException\n\tat 
java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat 
java.util.concurrent.FutureTask.", "status" : "ERROR" } ] }

dont je n'ai pas besoin. J'avais besoin de la façon dont il a été imprimé ci-dessus. Quelqu'un peut-il me dire pourquoi c'est arrivé de cette façon?

arsenal
la source

Réponses:

252

Pour indenter n'importe quel ancien JSON, liez-le simplement Objectcomme:

Object json = mapper.readValue(input, Object.class);

puis écrivez-le avec indentation:

String indented = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);

cela vous évite d'avoir à définir le POJO réel auquel mapper les données.

Ou vous pouvez également utiliser JsonNode(JSON Tree).

StaxMan
la source
Merci StaxMan, je suppose que cela fonctionne. Lorsque j'imprime en retrait, j'obtiens ce dont j'avais besoin. Mais quand j'utilise indenté pour ajouter dans le modèle afin que je puisse les afficher dans la page resultform. Il est toujours imprimé en deux trois lignes. J'ai mis à jour la question, peut-être que vous aurez une idée plus précise de ce qui se passe actuellement.
arsenal
Le problème est avec Spring alors - je suppose qu'il attend un POJO comme attribut, et non une chaîne pré-formatée. Donc, au lieu d'essayer de le formater vous-même, vous devez dire à Spring de le faire. Lors de l'utilisation de Jackson, il devrait être possible de le configurer pour utiliser l'indentation. Bien que pour être honnête, je ne sais pas pourquoi vous devez même l'indenter pour y répondre.
StaxMan
30
Bonjour, defaultPrettyPrintingWriter () est obsolète. Depuis la version 1.9, utilisez plutôt writerWithDefaultPrettyPrinter (). Référez-vous: jackson.codehaus.org/1.9.0/javadoc/org/codehaus/jackson/map/…
Browny Lin
6
Pour Jackson 2, utilisez SerializationFeature.INDENT_OUTPUT, comme spécifié par Marcelo C. ci
Mike R
une idée comment publier le montant de la valeur écrite en utilisant jackson?
Reyansh Mishra
125

La solution la plus simple et aussi la plus compacte (pour v2.3.3):

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)
Marcelo C.
la source
21
Vous pouvez en fait raccourcir encore plus cela: ObjectMapper mapper = new ObjectMapper.enable (SerializationFeature.INDENT_OUTPUT);
Jason Nichols
26

La nouvelle façon d'utiliser Jackson 1.9+ est la suivante:

Object json = OBJECT_MAPPER.readValue(diffResponseJson, Object.class);
String indented = OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
                               .writeValueAsString(json);

La sortie sera correctement formatée!

Marcello de Sales
la source
1
Malheureusement, cela n'aide pas si mon entrée est un objet créé à l'exécution, pas un autre json.
Innokenty
@Innokenty Alors sautez la première ligne.
muttonUp
2
@muttonUp Ouais, évidemment. Je l'ai même fait, je ne sais pas pourquoi j'ai laissé un commentaire aussi stupide =)
Innokenty
17

Pour Jackson 1.9, nous pouvons utiliser le code suivant pour une jolie impression.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
scalauser
la source
11

Je pense que c'est la technique la plus simple pour embellir les données json,

String indented = (new JSONObject(Response)).toString(4);

Response est une chaîne.

Passez simplement les 4 (indentSpaces) dans la toString()méthode.

Remarque: cela fonctionne correctement dans Android sans aucune bibliothèque. Mais en java, vous devez utiliser la bibliothèque org.json .

Aman Gupta - ShOoTeR
la source
3
Il convient de noter que cela utilise la bibliothèque JSON en Java (org.json) .
Steve Chambers
Sous Android, il peut utiliser direclty sans aucune bibliothèque.
Aman Gupta - ShOoTeR
String json = new GsonBuilder().setPrettyPrinting().create().toJson(map); String indentedJson = (new JSONObject(json)).toString(4);pour une raison quelconque, le second perd l'ordre des clés
Michail Michailidis
L'approche actuelle, malheureusement, ne gère pas la liste des objets json. Je veux dire [{"id": "1"}, {"id": "2"}]
Geniy
4

Cela semble être la réponse à votre question . Il dit qu'il utilise Spring, mais je pense que cela devrait toujours vous aider dans votre cas. Laissez-moi insérer le code ici pour que ce soit plus pratique:

import java.io.FileReader;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    MyClass myObject = mapper.readValue(new FileReader("input.json"), MyClass.class);
    // this is Jackson 1.x API only: 
    ObjectWriter writer = mapper.defaultPrettyPrintingWriter();
    // ***IMPORTANT!!!*** for Jackson 2.x use the line below instead of the one above: 
    // ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
    System.out.println(writer.writeValueAsString(myObject));
  }
}

class MyClass
{
  String one;
  String[] two;
  MyOtherClass three;

  public String getOne() {return one;}
  void setOne(String one) {this.one = one;}
  public String[] getTwo() {return two;}
  void setTwo(String[] two) {this.two = two;}
  public MyOtherClass getThree() {return three;}
  void setThree(MyOtherClass three) {this.three = three;}
}

class MyOtherClass
{
  String four;
  String[] five;

  public String getFour() {return four;}
  void setFour(String four) {this.four = four;}
  public String[] getFive() {return five;}
  void setFive(String[] five) {this.five = five;}
}
Daniel Kaplan
la source
Merci Daniel pour l'aide. La partie la plus difficile que j'ai est de savoir comment modéliser mon JSON dans une classe? Si je fais fonctionner cette partie, je peux facilement en coder le reste.
arsenal
Pouvez-vous jeter un œil à ma classe POJO que j'ai écrite à partir du JSON? Ça a l'air juste ou pas?
arsenal
3

Vous pouvez y parvenir en utilisant les méthodes ci-dessous:

1. Utilisation de Jackson depuis Apache

    String formattedData=new ObjectMapper().writerWithDefaultPrettyPrinter()
.writeValueAsString(YOUR_JSON_OBJECT);

Importer la classe ci-dessous:

import com.fasterxml.jackson.databind.ObjectMapper;

Sa dépendance gradle est:

compile 'com.fasterxml.jackson.core:jackson-core:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'

2. Utilisation de Gson de Google

String formattedData=new GsonBuilder().setPrettyPrinting()
    .create().toJson(YOUR_OBJECT);

Importer la classe ci-dessous:

import com.google.gson.Gson;

C'est gradle est:

compile 'com.google.code.gson:gson:2.8.2'

Ici, vous pouvez télécharger la version mise à jour correcte à partir du référentiel.

Md. Sajedul Karim
la source
2

ObjectMapper.readTree() peut le faire en une seule ligne:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(json));
Praneeth
la source
1
La raison pour laquelle j'aime cette réponse est qu'elle ne fait aucune conversion d'objet autre que le mappage direct aux types JSON. Tant que la chaîne d'entrée est JSON valide, nous savons que la chaîne de sortie sera un JSON sémantiquement équivalent.
M. Justin