Chuyển đổi JsonNode thành POJO


143

Điều này có vẻ hơi bất thường, nhưng tôi đang tìm kiếm một cách hiệu quả để chuyển đổi / ánh xạ a JsonNodethành a POJO.

Tôi lưu trữ một số thông tin về Mô hình của mình trong các tệp json và tôi phải hỗ trợ một vài phiên bản cho mô hình của mình.

Những gì tôi làm là tải tệp json trong bộ nhớ trong JsonNode, áp dụng một vài chiến lược phiên bản để làm cho nó phù hợp với phiên bản mới nhất của Mô hình của tôi.

    ObjectMapper mapper = new ObjectMapper();
    BufferedReader fileReader = new BufferedReader(new FileReader(projPath));

    JsonNode rootNode = mapper.readTree(fileReader);

    //Upgrade our file in memory
    applyVersioningStrategy(rootNode);

    ProjectModel project = mapJsonNodeToProject(rootNode);

Trừ khi có cách nhanh hơn để làm điều đó, có lẽ tôi sẽ chỉ đơn giản là áp dụng thủ công JsonNodescho Mô hình của mình

Câu trả lời:


264

Trong Jackson 2.4, bạn có thể chuyển đổi như sau:

MyClass newJsonNode = jsonObjectMapper.treeToValue(someJsonNode, MyClass.class);

nơi jsonObjectMapperlà Jackson ObjectMapper.


Trong các phiên bản cũ hơn của Jackson, nó sẽ là

MyClass newJsonNode = jsonObjectMapper.readValue(someJsonNode, MyClass.class);

18
Unfortunatelly không có biến thể treeToValue (TreeNode n, TypeReference <T>) giống như có cho readValue (). Tin xấu cho bất cứ ai đối phó với các loại phức tạp hơn với thuốc generic :(
Espinosa

13
@Espinosa Per jackson-databind # 1294 , bạn sẽ muốn một cái gì đó như (không may dài dòng hơn)jsonObjectMapper.readValue(jsonObjectMapper.treeAsTokens(someJsonNode), someTypeReference)
M. Justin

Đối với phiên bản cũ hơn, hãy sử dụng:objectMapper.treeToValue(jsonNode, MyClass.class)
amod

2
Bạn cũng có thể sử dụng phương pháp này trong StdDeserializer: p.codec.treeToValue .
galcyurio

@opedtrees jsonObjectMapper là một phiên bản của JsonObjectMapper hoặc chỉ là ObjectMapper
KNDheeraj

8

Cái này cần phải dùng mẹo:

mapper.readValue(fileReader, MyClass.class);

Tôi nói nên bởi vì tôi đang sử dụng nó với a String, không phải a BufferedReadernhưng nó vẫn hoạt động.

Đây là mã của tôi:

String inputString = // I grab my string here
MySessionClass sessionObject;
try {
    ObjectMapper objectMapper = new ObjectMapper();
    sessionObject = objectMapper.readValue(inputString, MySessionClass.class);

Đây là tài liệu chính thức cho cuộc gọi đó: http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(java.lang.String, java.lang.Class)

Bạn cũng có thể xác định trình giải nén tùy chỉnh khi khởi tạo ObjectMapper: http://wiki.fasterxml.com/JacksonHowToCustomDeserialulators

Chỉnh sửa: Tôi chỉ nhớ một cái gì đó khác. Nếu đối tượng của bạn đến có nhiều thuộc tính hơn so với POJOcó và bạn chỉ muốn bỏ qua các tính năng bổ sung bạn muốn đặt:

    objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Hoặc bạn sẽ gặp một lỗi mà nó không thể tìm thấy thuộc tính để thiết lập.


Tôi sẽ sử dụng một CustomDeserialators, nó sẽ giúp tôi đỡ đau đầu! Tôi cũng sẽ có thể áp dụng các chiến lược phiên bản của mình trong đó với rất ít sửa đổi. Cảm ơn!
Alexandre

5
Cú pháp bây giờ là: com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper (); mapper.disable (com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
llambda

Điểm tốt @llambda! Tôi chưa chạm vào ObjectMapper kể từ phiên bản 1.7.9, có vẻ như câu trả lời của tôi đã hết hạn bởi một vài phiên bản. Chắc chắn kiểm tra phiên bản Jackson bạn đang sử dụng.
Eric Barr

@EricBarr, tôi đang sử dụng Jackson v1.9.11 và cú pháp trong câu trả lời của bạn là chính xác cho phiên bản đó. Có lẽ họ đã cố gắng thay đổi mọi thứ và hoàn nguyên chúng một lần nữa trong các phiên bản mới hơn
Ivaylo Slavov

5

Nếu bạn đang sử dụng org.codehaus.jackson, điều này đã có thể kể từ 1.6. Bạn có thể chuyển đổi JsonNode thành POJO bằng ObjectMapper#readValue: http://jackson.codehaus.org/1.9.4/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(org.codehaus.jackson.JsonNode , java. lang.Class)


    ObjectMapper mapper = new ObjectMapper();
    JsonParser jsonParser = mapper.getJsonFactory().createJsonParser("{\"foo\":\"bar\"}");
    JsonNode tree = jsonParser.readValueAsTree();
    // Do stuff to the tree
    mapper.readValue(tree, Foo.class);

5
Phương pháp này dường như bị thiếu trong 2.4.4
Kevin Wittek

1
Xem icedtrees' câu trả lời dưới đây, một giải pháp phiên bản 2
Tim Buthe


3
String jsonInput = "{ \"hi\": \"Assume this is the JSON\"} ";
com.fasterxml.jackson.databind.ObjectMapper mapper =
    new com.fasterxml.jackson.databind.ObjectMapper();
MyClass myObject = objectMapper.readValue(jsonInput, MyClass.class);

Nếu đầu vào JSON của bạn có nhiều thuộc tính hơn POJO của bạn và bạn chỉ muốn bỏ qua các tính năng bổ sung trong Jackson 2.4, bạn có thể định cấu hình ObjectMapper của mình như sau. Cú pháp này khác với các phiên bản cũ của Jackson. (Nếu bạn sử dụng cú pháp sai, nó sẽ âm thầm không làm gì cả.)

mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNK‌​NOWN_PROPERTIES);
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.