พริตตี้พิมพ์ JSON ใน Java


217

ฉันกำลังใช้ และฉันต้องการพิมพ์ข้อมูล JSON ให้สวยขึ้น (ทำให้มนุษย์อ่านง่ายขึ้น)

ฉันไม่สามารถค้นหาฟังก์ชั่นนี้ภายในห้องสมุดนั้นได้ สิ่งนี้ประสบความสำเร็จได้อย่างไร

คำตอบ:


285

GSONสามารถทำได้ในวิธีที่ดี:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);

1
ฉันรวมรหัสเพื่อแยกสตริงลงใน JsonElement โดยปกติแล้วคุณมีสิ่งนั้นจากงานก่อนหน้านี้ที่คุณทำกับข้อมูล JSON แต่ฉันต้องการรวมไว้ที่นี่เพื่อให้การใช้งานชัดเจนยิ่งขึ้น
Ray Hulha

ตั้งแต่คำตอบนี้ช่วยฉัน ฉันได้เพิ่มโค้ดด้านล่างเพื่อย่อคำสั่งนี้ให้น้อยลงหากนี่คือสิ่งที่คุณกำลังมองหา String สาธารณะ prettifyJson (String json) {JsonElement jsonElement = ใหม่ JsonParser (). แจง (json); ส่งคืน GsonBuilder ใหม่ (). setPrettyPrinting (). create (). toJson (jsonElement); }
ahmad

2
เป็นไปได้ที่จะตอบคำถามของ OP โดยไม่ต้องการไลบรารีเพิ่มเติมเนื่องจากคุณสามารถเข้าถึงตัวแยกวิเคราะห์ JSON ที่ฝังอยู่ใน Rhino (JDK 1.7 ขึ้นไป) ฉันไม่คิดว่ามันเป็นการดีที่จะเพิ่มไลบรารี่ในโปรเจคเพื่อจัดรูปแบบเอาต์พุตการดีบัก scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
Agnes

1
ตรงกันข้ามกับทางเลือก org.json วิธี GSON ของการพิมพ์ที่สวยงามช่วยให้ลำดับขององค์ประกอบยังคงอยู่หลังจากการเปลี่ยนแปลง
Aydin K.

1
ขอบคุณสำหรับตัวชี้GsonBuilderตั้งแต่ฉันใช้gson.toJson(object)ฉันเพียงแค่เปลี่ยนอินสแตนซ์ของฉันจากGson gson = new Gson();เป็นGson gson = new GsonBuilder().setPrettyPrinting().create(); และรหัสของฉันยังคงทำงานได้ แต่พิมพ์วัตถุสวยแทนที่จะเป็นบรรทัดเดียว
cptully

153

ฉันใช้วิธีการในตัวของorg.jsonในการพิมพ์ข้อมูล

JSONObject json = new JSONObject(jsonString); // Convert text to object
System.out.println(json.toString(4)); // Print it with specified indentation

ลำดับของฟิลด์ใน JSON เป็นแบบสุ่มต่อการกำหนด คำสั่งซื้อที่เฉพาะเจาะจงขึ้นอยู่กับการแยกวิเคราะห์


7
ฉันชอบโซลูชันนี้เพราะคุณไม่จำเป็นต้องนำเข้าการอ้างอิงเพิ่มเติมเช่นคำตอบอื่น ๆ ที่แนะนำ
gdrt

3
ไม่มีการนำเข้าที่สำคัญ - import org.json.JSONObject;
MasterJoe2

อย่างไรก็ตามไม่มีเขตข้อมูลตามลำดับแบบสุ่มฉันต้องการตามลำดับที่เพิ่มเข้าไปหรือไม่
โทมัสเอเดรียน

@ThomasAdrian ไม่สามารถทำได้กับ org.json.JSONObject
Raghu Kiran

Underscore-java เก็บลำดับของแอททริบิวขณะทำการฟอร์แมต json
Valentyn Kolesnikov

37

ดูเหมือนว่าGSON จะสนับสนุนสิ่งนี้แม้ว่าฉันจะไม่รู้ว่าคุณต้องการเปลี่ยนจากห้องสมุดที่คุณใช้อยู่หรือไม่

จากคู่มือผู้ใช้:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);

4
ปัญหาเกี่ยวกับ GSON มันซับซ้อน json-simple นั้นง่ายกว่ามาก
mabuzer

1
ฉันไม่ได้ดูปัญหานี้ในรอบปี แต่ถ้าคุณยินดีที่จะแก้ไขซอร์สโค้ดสักหน่อยcode.google.com/p/json-simple/issues/detail?id=22มีข้อมูลบางอย่างเกี่ยวกับ ปรับปรุง json ง่ายด้วยการพิมพ์สวย
BuffaloBuffalo

มีเพียงสตริงที่ไม่มีการจัดรูปแบบการพิมพ์ที่สวยงาม :(
Cherry

มันพิมพ์สตริงด้วย \ r \ n
แจ็คสโตน

ขอบคุณ toString () เขียนทับในหนึ่งบรรทัด: new GsonBuilder (). setPrettyPrinting (). create (). toJson (this);
KeepAtIt

30

ด้วยแจ็คสัน ( com.fasterxml.jackson.databind):

ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject))

จาก: วิธีการเปิดใช้งานเอาต์พุต JSON พิมพ์สวย (แจ็คสัน)

ฉันรู้ว่านี่มีคำตอบอยู่แล้ว แต่ฉันต้องการเขียนแยกต่างหากที่นี่เพราะโอกาสคุณมี Jackson อยู่แล้วดังนั้นสิ่งที่คุณต้องมีก็คือโค้ดเพิ่มเติม


21

หากคุณกำลังใช้ Java API สำหรับ JSON การประมวลผล (JSR-353) การดำเนินงานแล้วคุณสามารถระบุสถานที่ให้บริการเมื่อคุณสร้างJsonGenerator.PRETTY_PRINTINGJsonGeneratorFactory

ตัวอย่างต่อไปนี้ได้รับการตีพิมพ์ครั้งแรกบนของบล็อกโพสต์

import java.util.*;
import javax.json.Json;
import javax.json.stream.*;

Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
JsonGeneratorFactory jgf = Json.createGeneratorFactory(properties);
JsonGenerator jg = jgf.createGenerator(System.out);

jg.writeStartObject()                    // {
    .write("name", "Jane Doe")           //    "name":"Jane Doe",
    .writeStartObject("address")         //    "address":{
        .write("type", 1)                //        "type":1,
        .write("street", "1 A Street")   //        "street":"1 A Street",
        .writeNull("city")               //        "city":null,
        .write("verified", false)        //        "verified":false
    .writeEnd()                          //    },
    .writeStartArray("phone-numbers")    //    "phone-numbers":[
        .writeStartObject()              //        {
            .write("number", "555-1111") //            "number":"555-1111",
            .write("extension", "123")   //            "extension":"123"
        .writeEnd()                      //        },
        .writeStartObject()              //        {
            .write("number", "555-2222") //            "number":"555-2222",
            .writeNull("extension")      //            "extension":null
        .writeEnd()                      //        }
    .writeEnd()                          //    ]
.writeEnd()                              // }
.close();

18

สถานการณ์ของฉันคือโครงการของฉันใช้ตัวแยกวิเคราะห์ JSON แบบดั้งเดิม (ไม่ใช่ JSR) ที่ไม่สนับสนุนการพิมพ์ที่ค่อนข้างสวย อย่างไรก็ตามฉันต้องการสร้างตัวอย่าง JSON ที่พิมพ์ออกมาสวย สิ่งนี้เป็นไปได้โดยไม่ต้องเพิ่มไลบรารีพิเศษใด ๆ ตราบใดที่คุณใช้ Java 7 ขึ้นไป:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine scriptEngine = manager.getEngineByName("JavaScript");
scriptEngine.put("jsonString", jsonStringNoWhitespace);
scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
String prettyPrintedJson = (String) scriptEngine.get("result");

3
นี่มันยอดเยี่ยมใช้
เอ็นจิ้น

เตือนถ้าคุณสนใจ: ScriptEngineManager ไม่ใช่ API
nclark

18

พิมพ์สวยด้วยGSONในบรรทัดเดียว:

System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(jsonString)));

นอกจากนี้อินไลน์นี้จะเทียบเท่ากับคำตอบที่ได้รับการยอมรับ


8

คำตอบที่มีอยู่ส่วนใหญ่ขึ้นอยู่กับไลบรารีภายนอกบางตัวหรือต้องการเวอร์ชัน Java พิเศษ นี่คือรหัสง่าย ๆ ในการพิมพ์สตริง JSON โดยใช้เฉพาะ Java APIs ทั่วไป (มีใน Java 7 ขึ้นไป แต่ยังไม่ได้ลองเวอร์ชันเก่ากว่า)

แนวคิดพื้นฐานคือการจัดรูปแบบทิกเกอร์ตามอักขระพิเศษใน JSON ตัวอย่างเช่นหากสังเกตว่า '{' หรือ '[' รหัสจะสร้างบรรทัดใหม่และเพิ่มระดับการเยื้อง

ข้อจำกัดความรับผิดชอบ: ฉันทดสอบเฉพาะกรณี JSON แบบง่าย ๆ (คู่คีย์ - ค่าพื้นฐาน, รายการ, JSON ซ้อนกัน) ดังนั้นจึงอาจต้องใช้งานสำหรับข้อความ JSON ทั่วไปเพิ่มเติมเช่นค่าสตริงพร้อมเครื่องหมายคำพูดหรืออักขระพิเศษ (\ n, \ t เป็นต้น)

/**
 * A simple implementation to pretty-print JSON file.
 *
 * @param unformattedJsonString
 * @return
 */
public static String prettyPrintJSON(String unformattedJsonString) {
  StringBuilder prettyJSONBuilder = new StringBuilder();
  int indentLevel = 0;
  boolean inQuote = false;
  for(char charFromUnformattedJson : unformattedJsonString.toCharArray()) {
    switch(charFromUnformattedJson) {
      case '"':
        // switch the quoting status
        inQuote = !inQuote;
        prettyJSONBuilder.append(charFromUnformattedJson);
        break;
      case ' ':
        // For space: ignore the space if it is not being quoted.
        if(inQuote) {
          prettyJSONBuilder.append(charFromUnformattedJson);
        }
        break;
      case '{':
      case '[':
        // Starting a new block: increase the indent level
        prettyJSONBuilder.append(charFromUnformattedJson);
        indentLevel++;
        appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        break;
      case '}':
      case ']':
        // Ending a new block; decrese the indent level
        indentLevel--;
        appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        prettyJSONBuilder.append(charFromUnformattedJson);
        break;
      case ',':
        // Ending a json item; create a new line after
        prettyJSONBuilder.append(charFromUnformattedJson);
        if(!inQuote) {
          appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        }
        break;
      default:
        prettyJSONBuilder.append(charFromUnformattedJson);
    }
  }
  return prettyJSONBuilder.toString();
}

/**
 * Print a new line with indention at the beginning of the new line.
 * @param indentLevel
 * @param stringBuilder
 */
private static void appendIndentedNewLine(int indentLevel, StringBuilder stringBuilder) {
  stringBuilder.append("\n");
  for(int i = 0; i < indentLevel; i++) {
    // Assuming indention using 2 spaces
    stringBuilder.append("  ");
  }
}

ในการอ่านครั้งแรกฉันไม่พอใจอย่างมากกับคำแนะนำนี้ แต่หลังจากอ่านคำตอบทั้งหมดนี่เป็นทางออกที่ดีที่สุด อย่างน้อยถ้ามันมีไว้สำหรับเอาท์พุทการดีบักเพียงบางส่วนและคุณไม่ต้องการลากในการอ้างอิงที่คุณอาจต้องการลบในภายหลังอีกครั้ง ขอบคุณมาก!
user2081279

7

ในหนึ่งบรรทัด:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

json-io libray ( https://github.com/jdereg/json-io ) เป็นห้องสมุดขนาดเล็ก (75K) ที่ไม่มีการขึ้นต่อกันอื่นนอกจาก JDK

นอกเหนือจากการพิมพ์ JSON ที่น่ารักแล้วคุณยังสามารถทำให้วัตถุ Java (กราฟวัตถุ Java ทั้งหมดที่มีวงรอบ) เป็น JSON และอ่านได้


7

ตอนนี้สามารถทำได้ด้วยไลบรารี JSONLib:

http://json-lib.sourceforge.net/apidocs/net/sf/json/JSONObject.html

หาก (และเฉพาะในกรณี) คุณใช้toString(int indentationFactor)วิธีโอเวอร์โหลดและไม่ใช่toString()วิธีมาตรฐาน

ฉันได้ตรวจสอบสิ่งนี้ใน API เวอร์ชันต่อไปนี้:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>

3
ในขณะที่ห้องสมุดนี้อาจช่วยตอบคำถามได้ดีกว่าหากจะรวมตัวอย่างของวิธีการใช้กับปัญหาพร้อมคำอธิบายบางอย่างเกี่ยวกับวิธีการใช้งาน
Francesco Menzani

1
ตกลงขอบคุณสำหรับคำติชม แม้ว่าจะจำได้ แต่คนอย่างฉันเป็นอาสาสมัครและไม่ได้รับเงินเพื่อให้บริการที่รับประกันมาตรฐานคุณภาพการประชุม เรามีเวลา จำกัด เพราะเรามักจะอยู่กลางงานหรือมีหน้าที่ครอบครัว นั่นเป็นเหตุผลที่ "ผู้แก้ไข" มีให้บริการสำหรับผู้อ่านดังนั้นเราจึงสามารถทำให้การโพสต์ของกันและกันเป็นประโยชน์มากขึ้น
Sridhar Sarnobat

6

การติดตามข้อมูลจำเพาะ JSON-P 1.0 ( JSR-353 ) โซลูชันที่เป็นปัจจุบันมากขึ้นสำหรับที่ระบุJsonStructure( JsonObjectหรือJsonArray) อาจมีลักษณะเช่นนี้:

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import javax.json.Json;
import javax.json.JsonStructure;
import javax.json.JsonWriter;
import javax.json.JsonWriterFactory;
import javax.json.stream.JsonGenerator;

public class PrettyJson {

    private static JsonWriterFactory FACTORY_INSTANCE;

    public static String toString(final JsonStructure status) {

        final StringWriter stringWriter = new StringWriter();

        final JsonWriter jsonWriter = getPrettyJsonWriterFactory()
                .createWriter(stringWriter);

        jsonWriter.write(status);
        jsonWriter.close();

        return stringWriter.toString();
    }

    private static JsonWriterFactory getPrettyJsonWriterFactory() {
        if (null == FACTORY_INSTANCE) {
            final Map<String, Object> properties = new HashMap<>(1);
            properties.put(JsonGenerator.PRETTY_PRINTING, true);
            FACTORY_INSTANCE = Json.createWriterFactory(properties);
        }
        return FACTORY_INSTANCE;
    }

}


5

คุณสามารถใช้ Gson ดังนี้

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonString = gson.toJson(object);

จากการโพสต์JSON พิมพ์สวยโดยใช้ Gson

หรือคุณสามารถใช้แจ็คสันด้านล่าง

ObjectMapper mapper = new ObjectMapper();
String perttyStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);

จากโพสต์Pretty print JSON ใน Java (Jackson)

หวังว่าจะช่วยได้!


4

ใช้ org json ลิงค์อ้างอิง

JSONObject jsonObject = new JSONObject(obj);
String prettyJson = jsonObject.toString(4);

ใช้ Gson ลิงค์อ้างอิง

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(obj);

ใช้แจ็คสัน ลิงค์อ้างอิง

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

ใช้ Genson การอ้างอิงการเชื่อมโยง

Genson prettyGenson = new GensonBuilder().useIndentation(true).create();
String prettyJson = prettyGenson.serialize(obj);


0

คุณสามารถใช้ไลบรารีjsonขนาดเล็ก

String jsonstring = ....;
JsonValue json = JsonParser.parse(jsonstring);
String jsonIndendedByTwoSpaces = json.toPrettyString("  ");

-2

ขีด-JavaU.formatJson(json)มีวิธีการคง รองรับรูปแบบได้ห้าประเภท: 2, 3, 4, แท็บและขนาดกะทัดรัด ฉันเป็นผู้ดูแลโครงการ ตัวอย่างสด

import com.github.underscore.lodash.U;

import static com.github.underscore.lodash.Json.JsonStringBuilder.Step.TABS;
import static com.github.underscore.lodash.Json.JsonStringBuilder.Step.TWO_SPACES;

public class MyClass {

    public static void main(String args[]) {
        String json = "{\"Price\": {"
        + "    \"LineItems\": {"
        + "        \"LineItem\": {"
        + "            \"UnitOfMeasure\": \"EACH\", \"Quantity\": 2, \"ItemID\": \"ItemID\""
        + "        }"
        + "    },"
        + "    \"Currency\": \"USD\","
        + "    \"EnterpriseCode\": \"EnterpriseCode\""
        + "}}";
        System.out.println(U.formatJson(json, TWO_SPACES)); 
        System.out.println(U.formatJson(json, TABS)); 
    }
}

เอาท์พุท:

{
  "Price": {
    "LineItems": {
      "LineItem": {
        "UnitOfMeasure": "EACH",
        "Quantity": 2,
        "ItemID": "ItemID"
      }
    },
    "Currency": "USD",
    "EnterpriseCode": "EnterpriseCode"
  }
}
{
    "Price": {
        "LineItems": {
            "LineItem": {
                "UnitOfMeasure": "EACH",
                "Quantity": 2,
                "ItemID": "ItemID"
            }
        },
        "Currency": "USD",
        "EnterpriseCode": "EnterpriseCode"
    }
}    
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.