Chuyển đổi chuỗi JSON thành đầu ra JSON đẹp bằng cách sử dụng Jackson


165

Đây là chuỗi JSON tôi có:

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

Tôi cần chuyển đổi JSON ở trên Stringthành Đầu ra JSON khá đẹp (sử dụng Jackson), như dưới đây:

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

Bất cứ ai có thể cung cấp cho tôi một ví dụ dựa trên ví dụ của tôi ở trên? Làm thế nào để đạt được kịch bản này? Tôi biết có rất nhiều ví dụ, nhưng tôi không thể hiểu chúng đúng. Bất kỳ trợ giúp sẽ được đánh giá cao với một ví dụ đơn giản.

Cập nhật:

Dưới đây là mã tôi đang sử dụng:

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

Nhưng điều này không hoạt động với cách tôi cần đầu ra như đã đề cập ở trên.

Đây là POJO tôi đang sử dụng cho JSON ở trên:

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

Ai đó có thể cho tôi biết liệu tôi đã nhận được POJO đúng cho JSON hay không?

Cập nhật:

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

Dòng dưới đây in ra một cái gì đó như thế này:

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

đó là cách tôi cần được thể hiện Nhưng khi tôi thêm nó vào mô hình như thế này:

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

Và sau đó hiển thị nó trong một trang jsp dạng kết quả như dưới đây:

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

    </fieldset>

Tôi nhận được một cái gì đó như thế này:

{ "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ái mà tôi không cần Tôi cần cách nó được in ra ở trên. Bất cứ ai có thể cho tôi biết tại sao nó xảy ra theo cách này?

Câu trả lời:


252

Để thụt lề bất kỳ JSON cũ nào, chỉ cần liên kết nó như Object, như:

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

và sau đó viết nó ra bằng cách thụt lề:

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

điều này tránh việc bạn phải xác định POJO thực tế để ánh xạ dữ liệu tới.

Hoặc bạn cũng có thể sử dụng JsonNode(Cây JSON).


Cảm ơn StaxMan, tôi đoán điều này đang hoạt động. Khi tôi in thụt ra tôi nhận được theo cách tôi cần. Nhưng khi tôi sử dụng thụt lề để thêm vào Mô hình để tôi có thể hiển thị chúng trong trang kết quả. Nó vẫn được in thành hai ba dòng. Tôi đã cập nhật câu hỏi, có thể bạn sẽ có thêm một số ý tưởng những gì đang xảy ra bây giờ.
kho vũ khí

Vấn đề là với Spring sau đó - tôi đoán nó mong đợi một POJO là thuộc tính chứ không phải là Chuỗi được định dạng trước. Vì vậy, thay vì cố gắng tự định dạng nó, bạn cần nói với Spring để làm điều này. Khi sử dụng Jackson, có thể cấu hình nó để sử dụng thụt đầu dòng. Mặc dù thành thật mà nói, tôi không chắc tại sao bạn thậm chí cần thụt lề để trả lời.
Staxman

30
Xin chào, defaultPrettyPrintingWriter () đã không được dùng nữa. Kể từ 1.9, hãy sử dụng wrWithDefaultPrettyPrinter (). Tham khảo: jackson.codehaus.org/1.9.0/javadoc/org/codehaus/jackson/map/ mẹo
Browny Lin

6
Đối với Jackson 2, hãy sử dụng serializationFeature.INDENT_OUTPUT, như được chỉ định bởi Marcelo C. bên dưới
Mike R

bất kỳ ý tưởng làm thế nào để xuất bản số lượng giá trị bằng văn bản bằng cách sử dụng jackson?
Reyansh Mishra

125

Giải pháp đơn giản nhất và cũng là nhỏ gọn nhất (cho v2.3.3):

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

21
Bạn thực sự có thể rút ngắn hơn nữa: ObjectMapper mapper = new ObjectMapper.enable (serializationFeature.INDENT_OUTPUT);
Jason Nichols

26

Cách mới sử dụng Jackson 1.9+ là như sau:

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

Đầu ra sẽ được định dạng chính xác!


1
Thật không may, điều đó không có ích nếu đầu vào của tôi là một đối tượng được tạo trong thời gian chạy chứ không phải json khác.
Innokenty

@Innokenty Sau đó bỏ qua dòng đầu tiên.
muttonUp

2
@muttonUp Vâng, rõ ràng. Tôi thậm chí đã làm điều đó, tôi không biết tại sao tôi lại để lại một bình luận ngu ngốc như vậy =)
Innokenty

17

Đối với Jackson 1.9, chúng tôi có thể sử dụng mã sau đây để in đẹp.

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

11

Tôi nghĩ rằng, đây là kỹ thuật đơn giản nhất để làm đẹp dữ liệu json,

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

trong đó Phản hồi là một Chuỗi.

Đơn giản chỉ cần vượt qua 4 (indentSpaces) trong toString()phương thức.

Lưu ý: Nó hoạt động tốt trong Android mà không cần bất kỳ thư viện. Nhưng trong java bạn phải sử dụng thư viện org.json .


3
Đáng lưu ý điều này là sử dụng thư viện JSON trong Java (org.json) .
Steve Chambers

Trong Android, nó có thể sử dụng direclty mà không cần bất kỳ thư viện nào.
Aman Gupta - ShOoTeR

String json = new GsonBuilder().setPrettyPrinting().create().toJson(map); String indentedJson = (new JSONObject(json)).toString(4);vì lý do nào đó, cái thứ hai đang mất thứ tự chìa khóa
Michail Michailidis

Thật không may, cách tiếp cận hiện tại không xử lý danh sách các đối tượng json. Ý tôi là [{"id": "1"}, {"id": "2"}]
Geniy

4

Có vẻ như nó có thể là câu trả lời cho câu hỏi của bạn . Nó nói rằng nó đang sử dụng Spring, nhưng tôi nghĩ rằng nó vẫn sẽ giúp bạn trong trường hợp của bạn. Hãy để tôi đặt nội tuyến mã ở đây để thuận tiện hơn:

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

Cảm ơn Daniel đã giúp đỡ. Phần khó nhất tôi đang có là làm thế nào để mô hình hóa JSON của tôi thành một Class? Nếu tôi làm cho phần đó hoạt động, tôi có thể dễ dàng mã phần còn lại của nó.
kho vũ khí

Bạn có thể xem lớp POJO của tôi mà tôi đã viết từ JSON không? Có vẻ đúng hay không?
kho vũ khí

3

Bạn có thể đạt được điều này bằng cách sử dụng các cách dưới đây:

1. Sử dụng Jackson từ Apache

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

Nhập lớp dưới đây:

import com.fasterxml.jackson.databind.ObjectMapper;

Đó là phụ thuộc lớp là:

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. Sử dụng Gson từ Google

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

Nhập lớp dưới đây:

import com.google.gson.Gson;

Đó là lớp:

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

Tại đây, bạn có thể tải về phiên bản cập nhật chính xác từ kho lưu trữ.


2

ObjectMapper.readTree() có thể làm điều này trong một dòng:

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

1
Lý do tôi thích câu trả lời này là vì nó không thực hiện bất kỳ chuyển đổi đối tượng nào ngoài việc ánh xạ trực tiếp sang các loại JSON. Miễn là chuỗi đầu vào là JSON hợp lệ, chúng tôi biết chuỗi đầu ra sẽ tương đương về mặt ngữ nghĩa.
M. Justin
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.