JSON in đẹp trong Java


217

Tôi đang sử dụng và tôi cần in dữ liệu JSON đẹp (làm cho nó dễ đọc hơn với con người).

Tôi chưa thể tìm thấy chức năng này trong thư viện đó. Làm thế nào là điều này thường đạt được?

Câu trả lời:


284

GSON có thể làm điều này một cách tốt đẹp:

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

1
Vâng, tôi đã bao gồm mã để phân tích một chuỗi thành JsonEuity, thông thường bạn đã có mã đó từ công việc trước đó bạn làm với dữ liệu JSON. Nhưng tôi muốn bao gồm nó ở đây để làm cho việc sử dụng rõ ràng hơn.
Ray Hulha

Vì câu trả lời này đã giúp tôi. Tôi đã thêm mã dưới đây để thu nhỏ câu lệnh này thành ít dòng hơn nếu đây là những gì bạn đang tìm kiếm. chuỗi công khai prettifyJson (Chuỗi json) {JsonEuity jsonEuity = new JsonParser (). parse (json); trả về GsonBuilder mới (). setPrettyPrinting (). created (). toJson (jsonEuity); }
ahmad

2
Có thể trả lời câu hỏi của OP mà không cần thêm thư viện, vì bạn chỉ cần truy cập trình phân tích cú pháp JSON được nhúng trong Rhino (JDK 1.7 trở lên). Tôi không nghĩ rằng nên thêm một thư viện vào một dự án chỉ để định dạng một số đầu ra gỡ lỗi. scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
Agnes

1
Trái ngược với phương án org.json, cách in đẹp của GSON giữ nguyên thứ tự của các phần tử sau khi chuyển đổi.
Aydin K.

1
Cảm ơn con trỏ tới GsonBuilder, vì tôi đang sử dụng, gson.toJson(object)tôi chỉ cần thay đổi phần khởi tạo của mình từ Gson gson = new Gson();sang Gson gson = new GsonBuilder().setPrettyPrinting().create(); và mã của tôi tiếp tục hoạt động nhưng in đẹp đối tượng thay vì một dòng.
cptully

153

Tôi đã sử dụng các phương thức tích hợp org.json để in dữ liệu.

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

Thứ tự của các trường trong JSON là ngẫu nhiên theo định nghĩa. Một thứ tự cụ thể là tùy thuộc vào việc thực hiện phân tích cú pháp.


7
Tôi cũng thích giải pháp này, vì bạn không cần nhập phụ thuộc bổ sung như các câu trả lời khác đề xuất.
gdrt

3
Thiếu một nhập khẩu quan trọng - nhập org.json.JSONObject;
MasterJoe2

Có cách nào để KHÔNG có các trường theo thứ tự ngẫu nhiên không, tôi muốn nó theo thứ tự tôi đã thêm chúng?
Thomas Adrian

@ThomasAdrian không thể thực hiện được với org.json.JSONObject.
Raghu Kiran

Underscore-java giữ trật tự thuộc tính trong khi định dạng json.
Valentyn Kolesnikov

37

Có vẻ như GSON hỗ trợ điều này, mặc dù tôi không biết nếu bạn muốn chuyển từ thư viện bạn đang sử dụng.

Từ hướng dẫn sử dụng:

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

4
Vấn đề với GSON, nó phức tạp, đơn giản dễ dàng hơn nhiều.
mabuzer

1
Tôi đã không xem xét vấn đề này trong hơn một năm, nhưng nếu bạn sẵn sàng sửa đổi mã nguồn một chút, code.google.com/p/json-simple/issues/detail?id=22 có một số thông tin về tăng cường json-đơn giản với in ấn đẹp.
BuffaloBuffalo

Chỉ có chuỗi mà không có bất kỳ định dạng in đẹp :(
Cherry

nó in String với \ r \ n
Stone Jack

Cảm ơn. ghi đè toString () trong một dòng: new GsonBuilder (). setPrettyPrinting (). created (). toJson (this);
KeepAtIt

30

Với Jackson ( com.fasterxml.jackson.databind):

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

Từ: Cách bật đầu ra JSON in đẹp (Jackson)

Tôi biết điều này đã có trong câu trả lời, nhưng tôi muốn viết riêng ở đây vì rất có thể, bạn đã có Jackson như một người phụ thuộc và vì vậy tất cả những gì bạn cần sẽ là một dòng mã bổ sung


21

Nếu bạn đang sử dụng triển khai API Java để xử lý JSON (JSR-353) thì bạn có thể chỉ định thuộc JsonGenerator.PRETTY_PRINTINGtính khi bạn tạoJsonGeneratorFactory .

Ví dụ sau đây đã được xuất bản ban đầu trên bài đăng trên blog của tôi .

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

Tình huống của tôi là dự án của tôi sử dụng trình phân tích cú pháp JSON kế thừa (không phải là JSR) không hỗ trợ in ấn đẹp. Tuy nhiên, tôi cần tạo ra các mẫu JSON được in đẹp; điều này là có thể mà không cần phải thêm bất kỳ thư viện bổ sung nào miễn là bạn đang sử dụng Java 7 trở lên:

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
Điều này thật tuyệt vời, hãy sử dụng công cụ js để làm điều đó, đơn giản hơn nhiều
med116

cảnh báo nếu bạn quan tâm: ScriptEngineManager không phải là API.
nclark


8

Hầu hết các câu trả lời hiện có hoặc phụ thuộc vào một số thư viện bên ngoài hoặc yêu cầu một phiên bản Java đặc biệt. Đây là một mã đơn giản để in một chuỗi JSON đẹp, chỉ sử dụng các API Java chung (có sẵn trong Java 7 để cao hơn; mặc dù chưa thử phiên bản cũ hơn).

Ý tưởng cơ bản là điều chỉnh định dạng dựa trên các ký tự đặc biệt trong JSON. Ví dụ: nếu quan sát thấy '{' hoặc '[', mã sẽ tạo một dòng mới và tăng mức thụt lề.

Tuyên bố miễn trừ trách nhiệm: Tôi chỉ thử nghiệm điều này cho một số trường hợp JSON đơn giản (cặp giá trị khóa cơ bản, danh sách, JSON lồng nhau) để có thể cần một số công việc cho văn bản JSON chung hơn, như giá trị chuỗi có dấu ngoặc kép bên trong hoặc ký tự đặc biệt (\ n, \ v.v.)

/**
 * 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("  ");
  }
}

Trong lần đọc đầu tiên, tôi rất khó chịu với đề nghị này, nhưng sau khi đọc tất cả các câu trả lời, đây là giải pháp tốt nhất. Ít nhất, nếu nó chỉ dành cho một số đầu ra gỡ lỗi và bạn không muốn kéo theo các phụ thuộc, thì bạn có thể muốn xóa lại sau này. Cảm ơn rât nhiều!
dùng2081279

7

Trong một dòng:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

Thư viện json-io ( https://github.com/jdereg/json-io ) là một thư viện nhỏ (75K) không có phụ thuộc nào khác ngoài JDK.

Ngoài JSON in ấn đẹp, bạn có thể tuần tự hóa các đối tượng Java (toàn bộ biểu đồ đối tượng Java theo chu kỳ) thành JSON, cũng như đọc chúng trong.


7

Bây giờ điều này có thể đạt được với thư viện JSONLib:

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

Nếu (và chỉ khi) bạn sử dụng toString(int indentationFactor)phương thức quá tải chứ không phải tiêu chuẩntoString() phương thức .

Tôi đã xác minh điều này trên phiên bản sau của API:

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

3
Mặc dù thư viện này có thể giúp trả lời câu hỏi, nhưng sẽ tốt hơn nếu bao gồm một ví dụ về cách áp dụng cho vấn đề này với một số giải thích liên quan đến cách thức hoạt động của nó.
Francesco Menzani

1
Ok cảm ơn đã phản hồi. Mặc dù nhớ, những người như tôi là tình nguyện viên và không được trả tiền để cung cấp dịch vụ đảm bảo đáp ứng các tiêu chuẩn chất lượng. Chúng tôi có thời gian hạn chế vì chúng tôi thường ở giữa công việc hoặc có nhiệm vụ gia đình. Đó là lý do tại sao "chỉnh sửa" có sẵn cho độc giả, vì vậy chúng tôi có thể làm cho bài đăng của nhau trở nên hữu ích hơn.
Sridhar Sarnobat

6

Theo thông số kỹ thuật JSON-P 1.0 ( JSR-353 ), một giải pháp hiện tại hơn cho một JsonStructure( JsonObjecthoặc JsonArray) nhất định có thể trông như thế này:

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

Bạn có thể sử dụng Gson như dưới đây

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

Từ bài viết JSON in đẹp bằng Gson

Ngoài ra, bạn có thể sử dụng Jackson như dưới đây

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

Từ bài viết JSON in khá đẹp trong Java (Jackson)

Hy vọng điều này giúp đỡ!


4

Sử dụng org json. Liên kết tham khảo

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

Sử dụng Gson. Liên kết tham khảo

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

Sử dụng Jackson. Liên kết tham khảo

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

Sử dụng Genson. Liên kết tham khảo .

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

1

Điều này làm việc cho tôi, sử dụng Jackson:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)

Điều này mapperđến từ đâu?
Sertage

0

Bạn có thể sử dụng thư viện json nhỏ

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

-2

Underscore-java có phương thức tĩnh U.formatJson(json). Năm loại định dạng được hỗ trợ: 2, 3, 4, tab và nhỏ gọn. Tôi là người duy trì dự án. Ví dụ sống

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

Đầu ra:

{
  "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"
    }
}    
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.