Konversi JSON String ke Pretty Print output JSON menggunakan Jackson

165

Ini adalah string JSON yang saya miliki:

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

Saya perlu mengubah JSON di atas Stringke dalam Pretty Print JSON Output (menggunakan Jackson), seperti di bawah ini:

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

Adakah yang bisa memberikan saya contoh berdasarkan contoh saya di atas? Bagaimana cara mencapai skenario ini? Saya tahu ada banyak contoh, tetapi saya tidak dapat memahaminya dengan benar. Bantuan apa pun akan dihargai dengan contoh sederhana.

Diperbarui:

Di bawah ini adalah kode yang saya gunakan:

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

Tetapi ini tidak bekerja dengan cara saya membutuhkan output seperti yang disebutkan di atas.

Inilah POJO yang saya gunakan untuk JSON di atas:

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

Adakah yang bisa memberi tahu saya apakah saya mendapatkan POJO yang tepat untuk JSON atau tidak?

Diperbarui:

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

Baris di bawah ini mencetak sesuatu seperti ini:

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

itulah cara saya perlu ditampilkan. Tetapi ketika saya menambahkannya ke model seperti ini:

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

Dan kemudian menunjukkannya di halaman jsp formform seperti di bawah ini:

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

    </fieldset>

Saya mendapatkan sesuatu seperti ini:

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

yang tidak saya butuhkan. Saya perlu cara itu dicetak di atas. Adakah yang bisa memberi tahu saya mengapa itu terjadi seperti ini?

gudang senjata
sumber

Jawaban:

252

Untuk membuat indentasi JSON lama, ikat saja seperti Object, seperti:

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

dan kemudian menulisnya dengan lekukan:

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

ini menghindari keharusan Anda menentukan POJO aktual untuk memetakan data.

Atau Anda bisa menggunakan JsonNode(JSON Tree) juga.

StaxMan
sumber
Terima kasih StaxMan, saya kira ini berfungsi. Ketika saya mencetak indentasi saya mendapatkan apa yang saya butuhkan. Tetapi ketika saya menggunakan indentasi untuk menambahkan ke dalam Model sehingga saya bisa menunjukkannya di halaman formform. Masih dicetak dalam dua tiga baris. Saya telah memperbarui pertanyaan, mungkin Anda akan mendapatkan lebih banyak ide tentang apa yang terjadi sekarang.
arsenal
Masalahnya adalah dengan Spring - saya kira itu mengharapkan POJO sebagai atribut, dan bukan String yang telah diformat sebelumnya. Jadi, alih-alih mencoba memformatnya sendiri, Anda harus memberi tahu Spring untuk melakukan ini. Saat menggunakan Jackson, harus dimungkinkan untuk mengkonfigurasinya untuk menggunakan indentasi. Meskipun jujur, saya tidak yakin mengapa Anda bahkan perlu indentasi untuk tanggapan.
StaxMan
30
Hai, defaultPrettyPrintingWriter () telah ditinggalkan. Sejak 1.9, gunakan writerWithDefaultPrettyPrinter () sebagai gantinya. Lihat: jackson.codehaus.org/1.9.0/javadoc/org/codehaus/jackson/map/…
Browny Lin
6
Untuk Jackson 2, gunakan SerializationFeature.INDENT_OUTPUT, seperti yang ditentukan oleh Marcelo C. di bawah ini
Mike R
tahu bagaimana cara mempublikasikan jumlah nilai tertulis menggunakan jackson?
Reyansh Mishra
125

Solusi paling sederhana dan juga paling ringkas (untuk v2.3.3):

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)
Marcelo C.
sumber
21
Anda sebenarnya dapat mempersingkat lebih jauh: ObjectMapper mapper = new ObjectMapper.enable (SerializationFeature.INDENT_OUTPUT);
Jason Nichols
26

Cara baru menggunakan Jackson 1.9+ adalah sebagai berikut:

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

Output akan diformat dengan benar!

Marcello de Sales
sumber
1
Sayangnya, itu tidak membantu jika input saya adalah objek runtime yang dibuat, bukan json lain.
Innokenty
@Innokenty Lalu lewati baris pertama.
muttonUp
2
@muttonUp Ya, tentu saja. Saya bahkan telah melakukannya, saya tidak tahu mengapa saya meninggalkan komentar bodoh =)
Innokenty
17

Untuk Jackson 1.9, Kita dapat menggunakan kode berikut untuk mencetak cantik.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
pembuat skala
sumber
11

Saya pikir, ini adalah teknik paling sederhana untuk mempercantik data json,

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

di mana Respon adalah sebuah String.

Cukup lewati metode 4 (indentSpaces) toString().

Catatan: Ini berfungsi dengan baik di android tanpa perpustakaan. Tetapi dalam java Anda harus menggunakan pustaka org.json .

Aman Gupta - ShOoTeR
sumber
3
Perlu dicatat ini menggunakan perpustakaan JSON di Java (org.json) .
Steve Chambers
Di android, dapat menggunakan direclty tanpa pustaka.
Aman Gupta - ShOoTeR
String json = new GsonBuilder().setPrettyPrinting().create().toJson(map); String indentedJson = (new JSONObject(json)).toString(4);untuk beberapa alasan yang kedua kehilangan urutan kunci
Michail Michailidis
Pendekatan saat ini, sayangnya, tidak menangani daftar objek json. Maksud saya [{"id": "1"}, {"id": "2"}]
Geniy
4

Sepertinya ini mungkin jawaban untuk pertanyaan Anda . Dikatakan itu menggunakan Spring, tapi saya pikir itu masih akan membantu Anda dalam kasus Anda. Biarkan saya sebaris kode di sini sehingga lebih nyaman:

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
sumber
Terima kasih Daniel atas bantuannya. Bagian tersulit yang saya miliki adalah bagaimana memodelkan JSON saya menjadi Kelas? Jika saya membuat bagian itu berfungsi, saya dapat dengan mudah kode sisanya.
arsenal
Bisakah Anda melihat ke kelas POJO saya yang saya tulis dari JSON? Terlihat benar atau tidak?
arsenal
3

Anda dapat mencapai ini menggunakan cara-cara berikut:

1. Menggunakan Jackson dari Apache

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

Impor di bawah kelas:

import com.fasterxml.jackson.databind.ObjectMapper;

Ketergantungan gradle adalah:

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. Menggunakan Gson dari Google

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

Impor di bawah kelas:

import com.google.gson.Gson;

Gradle-nya adalah:

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

Di sini, Anda dapat mengunduh versi terbaru yang benar dari repositori.

Md. Sajedul Karim
sumber
2

ObjectMapper.readTree() dapat melakukan ini dalam satu baris:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(json));
Praneeth
sumber
1
Alasan saya menyukai jawaban ini adalah karena tidak melakukan konversi objek sama sekali selain pemetaan langsung ke tipe JSON. Selama string input adalah JSON yang valid, kita tahu string output akan menjadi JSON yang secara semantik setara.
M. Justin