JsonNode'u POJO'ya dönüştür


143

Bu biraz olağandışı görünebilir, ama ben / dönüşümü bir haritaya etkin yol arıyorum JsonNodebir içine POJO.

Modelimin bazı bilgilerini json dosyalarında saklıyorum ve modelimin birkaç sürümünü desteklemem gerekiyor.

Ne yaptığım json dosyasını bellekte bir JsonNode yüklemek, benim Modelinin son sürümü eşleştirmek için birkaç sürüm stratejileri uygulamak.

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

Bunu yapmak için hızlı bir yolu var olmadığı sürece, muhtemelen sadece elle uygulayarak sona erecek JsonNodesbenim Modeli

Yanıtlar:


264

Jackson 2.4'te aşağıdaki gibi dönüştürebilirsiniz:

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

jsonObjectMapperJackson nerede ObjectMapper.


Jackson'ın eski sürümlerinde,

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

19
Ne yazık ki readValue () için olduğu gibi treeToValue (TreeNode n, TypeReference <T> tipi) varyantı yoktur. Jeneriklerle daha karmaşık tiplerle uğraşan herkes için kötü haber :(
Espinosa

13
@Espinosa Jackson-databind # 1294'te , (maalesef daha ayrıntılı) gibi bir şey isteyeceksinizjsonObjectMapper.readValue(jsonObjectMapper.treeAsTokens(someJsonNode), someTypeReference)
M. Justin

Eski sürüm kullanımı için:objectMapper.treeToValue(jsonNode, MyClass.class)
amod

2
Ayrıca StdDeserializer bu yöntemi kullanabilirsiniz: p.codec.treeToValue.
galcyurio

@icedtrees jsonObjectMapper, JsonObjectMapper veya yalnızca ObjectMapper
KNDheeraj'ın

8

Bu hile yapmalı:

mapper.readValue(fileReader, MyClass.class);

Yapmalıyım diyorum çünkü bunu a ile kullanıyorum String, değil BufferedReaderama yine de çalışmalı.

İşte benim kod:

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

Bu görüşme için resmi belgeler: http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(java.lang.String, java.lang.Class)

Eğer örneğini olduğunda da özel bir deserializer tanımlayabilirsiniz ObjectMapper: http://wiki.fasterxml.com/JacksonHowToCustomDeserializers

Düzenleme: Sadece başka bir şey hatırladım. Nesneniz gelen özelliklerden daha fazla özelliğe POJOsahipse ve yalnızca ekstraları yoksaymak istiyorsanız bunu ayarlamak istersiniz:

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

Veya ayarlanacak özelliği bulamadığı bir hata alırsınız.


CustomDeserializer'ları kullanacağım, bu beni çok fazla baş ağrısından kurtaracak! Sürüm stratejilerimi orada çok az değişiklikle de uygulayabileceğim. Teşekkürler!
Alexandre

5
Sözdizimi şimdi: com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper (); mapper.disable (com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
llambda

İyi nokta @llambda! 1.7.9 sürümünden beri ObjectMapper'e dokunmadım, cevabım birkaç sürüm tarafından güncel değil gibi görünüyor. Jackson'ın hangi sürümünü kullandığınızı kesinlikle kontrol edin.
Eric Barr

@EricBarr, Jackson v1.9.11 kullanıyorum ve cevabınızdaki sözdizimi bu sürüm için doğru olanı. Belki bir şeyleri değiştirmeye çalıştılar ve onları daha yeni sürümlerde geri aldılar
Ivaylo Slavov

5

Org.codehaus.jackson kullanıyorsanız, bu 1.6'dan beri mümkün. Bir JsonNode'u şu adresten POJO'ya dönüştürebilirsiniz 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
Bu yöntemler 2.4.4'te eksik görünüyor
Kevin Wittek

1
Sürüm 2 çözümü için aşağıdaki icedtrees'in cevabına bakınız
Tim Büthe


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

JSON girişiniz POJO'nuzdan daha fazla özelliğe sahipse ve yalnızca Jackson 2.4'teki ekstraları yoksaymak istiyorsanız, ObjectMapper'ınızı aşağıdaki gibi yapılandırabilirsiniz. Bu sözdizimi eski Jackson sürümlerinden farklıdır. (Yanlış sözdizimi kullanırsanız, sessizce hiçbir şey yapmaz.)

mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNK‌​NOWN_PROPERTIES);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.