Converti stringa JSON in output JSON Pretty Print usando Jackson


165

Questa è la stringa JSON che ho:

{"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}]}

Devo convertire il JSON sopra Stringin Output JSON Pretty Print (usando Jackson), come di seguito:

{
    "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
        }
    ]
}

Qualcuno può fornirmi un esempio basato sul mio esempio sopra? Come realizzare questo scenario? So che ci sono molti esempi, ma non sono in grado di capirli correttamente. Qualsiasi aiuto sarà apprezzato con un semplice esempio.

aggiornato:

Di seguito è riportato il codice che sto usando:

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

Ma questo non funziona con il modo in cui avevo bisogno dell'output come menzionato sopra.

Ecco il POJO che sto usando per il JSON sopra:

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

Qualcuno può dirmi se ho ottenuto il POJO giusto per il JSON o no?

aggiornato:

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 riga sotto stampa qualcosa del genere:

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"
  } ]
}

che è il modo in cui avevo bisogno di essere mostrato. Ma quando lo aggiungo al modello in questo modo:

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

E poi lo mostra in una pagina jsp del form dei risultati come di seguito:

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

    </fieldset>

Ottengo qualcosa del genere:

{ "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" } ] }

di cui non ho bisogno. Avevo bisogno del modo in cui è stato stampato sopra. Qualcuno può dirmi perché è successo in questo modo?

Risposte:


252

Per indentare qualsiasi vecchio JSON, basta associarlo come Object, come:

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

e poi scriverlo con rientro:

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

questo evita di dover definire il POJO effettivo a cui mappare i dati.

Oppure puoi usare anche JsonNode(JSON Tree).


Grazie StaxMan, immagino che funzioni. Quando stampo rientrato, mi intrometto nel modo che mi serviva. Ma quando uso rientro per aggiungere nel modello in modo da poterli mostrare nella pagina del modulo dei risultati. Viene ancora stampato in due tre righe. Ho aggiornato la domanda, forse avrai qualche idea in più su cosa sta succedendo ora.
arsenale,

Il problema è quindi con Spring: suppongo che si aspetti un POJO come attributo e non una stringa preformattata. Quindi, invece di provare a formattarlo da solo, dovresti dire a Spring di farlo. Quando si utilizza Jackson, dovrebbe essere possibile configurarlo per utilizzare il rientro. Anche se ad essere sincero, non sono sicuro del motivo per cui è necessario rientrare nella risposta.
StaxMan,

30
Salve, defaultPrettyPrintingWriter () è stato deprecato. Dall'1.9, utilizzare writerWithDefaultPrettyPrinter () invece. Fare riferimento: jackson.codehaus.org/1.9.0/javadoc/org/codehaus/jackson/map/…
Lin

6
Per Jackson 2, utilizza SerializationFeature.INDENT_OUTPUT, come specificato da Marcelo C. di seguito
Mike R

qualche idea su come pubblicare la quantità di valore scritto usando jackson?
Reyansh Mishra il

125

La soluzione più semplice e anche più compatta (per v2.3.3):

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)

21
Puoi effettivamente accorciarlo ulteriormente: ObjectMapper mapper = new ObjectMapper.enable (SerializationFeature.INDENT_OUTPUT);
Jason Nichols,

26

Il nuovo modo di usare Jackson 1.9+ è il seguente:

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

L'output sarà formattato correttamente!


1
Sfortunatamente, ciò non aiuta se il mio input è un oggetto creato in runtime, non un altro json.
Innokenty,

@Innokenty Quindi salta la prima riga.
muttonUp

2
@muttonUp Sì, ovviamente. L'ho anche fatto, non so perché ho lasciato un commento così stupido =)
Innokenty

17

Per Jackson 1.9, possiamo usare il seguente codice per pretty print.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);

11

Penso che questa sia la tecnica più semplice per abbellire i dati json,

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

dove Response è una stringa.

Basta passare i 4 (indentSpaces) nel toString()metodo.

Nota: funziona bene su Android senza alcuna libreria. Ma in Java devi usare la libreria org.json .


3
Vale la pena notare che sta usando la libreria JSON in Java (org.json) .
Steve Chambers,

In Android, può usare Direclty senza libraray.
Aman Gupta - SHOoTeR,

String json = new GsonBuilder().setPrettyPrinting().create().toJson(map); String indentedJson = (new JSONObject(json)).toString(4);per qualche motivo il secondo sta perdendo l'ordine delle chiavi
Michail Michailidis,

L'approccio attuale, sfortunatamente, non gestisce l'elenco di oggetti json. Intendo [{"id": "1"}, {"id": "2"}]
Geniy,

4

Sembra che potrebbe essere la risposta alla tua domanda . Dice che sta usando Spring, ma penso che dovrebbe comunque aiutarti nel tuo caso. Permettetemi di inserire il codice qui, quindi è più conveniente:

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

Grazie Daniel per l'aiuto. La parte più difficile che sto avendo è come modellare il mio JSON in una classe? Se riesco a far funzionare quella parte, posso facilmente codificarne il resto.
arsenale,

Puoi dare un'occhiata alla mia classe POJO che ho scritto dal JSON? Sembra giusto o no?
arsenale

3

Puoi farlo usando i seguenti modi:

1. Utilizzo di Jackson da Apache

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

Importare classe sotto:

import com.fasterxml.jackson.databind.ObjectMapper;

La sua dipendenza graduale è:

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. Utilizzo di Gson da Google

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

Importare classe sotto:

import com.google.gson.Gson;

Il suo grado è:

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

Qui, è possibile scaricare la versione aggiornata corretta dal repository.


2

ObjectMapper.readTree() puoi farlo in una riga:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(json));

1
Il motivo per cui mi piace questa risposta è che non esegue alcuna conversione di oggetti a parte il mapping diretto ai tipi JSON. Finché la stringa di input è JSON valida, sappiamo che la stringa di output sarà JSON semanticamente equivalente.
M. Justin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.