I am in the process of upgrading Jackson from 1.9.4 to 2.2.0. The transition has been smooth, except I can't seem to get array parsing for Objects working. In 1.9.4 I could do this:
private List<Subjects> mSubjects;
mSubjects = objectMapper.readValue(subjectsJsonArrayNode, new TypeReference<List<Subjects>>() {});
With Jackson 2.2.0, I get a "cannot resolve method" compile-time error. Jackson's ObjectMapper header file for 1.9.4 contains these readValue methods for JsonNodes:
public <T> T readValue(JsonNode root, java.lang.Class<T> valueType)
public <T> T readValue(JsonNode root, org.codehaus.jackson.type.TypeReference valueTypeRef)
public <T> T readValue(JsonNode root, org.codehaus.jackson.type.JavaType valueType)
And Jackson 2.2.0's header file:
public <T> T readValue(JsonParser jsonParser, java.lang.Class<T> tClass)
public <T> T readValue(JsonParser jsonParser, com.fasterxml.jackson.core.type.TypeReference<?> typeReference)
public final <T> T readValue(JsonParser jsonParser, com.fasterxml.jackson.core.type.ResolvedType resolvedType)
public <T> T readValue(JsonParser jsonParser, com.fasterxml.jackson.databind.JavaType javaType)
So I need to switch from passing a JsonNode to a JsonParser, but I'm not quite sure how to make that transition. That said, I'm not sure if I'm even going down the right path because JsonParser is defined as an abstract class so I can't even easily initialize an instance to play around with it.
For those who come without an answer, here is a temporary solution I have in place where I iterate and manually parse each object:
private List<Subjects> mSubjects = new ArrayList<Subjects>();
for(JsonNode subjectJsonNode : subjectsJsonArrayNode) {
mSubjects.add(objectMapper.treeToValue(subjectJsonNode, Subject.class));
}
You can simply call the JsonNode.traverse()
method to get the JsonParser
.
Tested with the following simple example:
public class App {
public static class Foo {
public int foo;
}
public static void main(String[] args) {
String json = "{\"someArray\":[{\"foo\":5},{\"foo\":6},{\"foo\":7}]}";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(json);
node = node.get("someArray");
TypeReference<List<Foo>> typeRef = new TypeReference<List<Foo>>(){};
List<Foo> list = mapper.readValue(node.traverse(), typeRef);
for (Foo f : list) {
System.out.println(f.foo);
}
}
}
outputs:
5
6
7
I use this method for lists:
/**
* Returns a list collection of any specified type
* @param jsonValue the json string content to deserialize
* @param type the type to serialize into
* @return a list of specified type
*/
public List<?> readJSONToList(String jsonValue,Class<?> type){
List<?> objDTOS=null;
try {
//get json content without root name
JsonNode root= objectMapper.readTree(jsonValue).get(getRootName());
TypeFactory tf = objectMapper.getTypeFactory();
JavaType listOfObjs = tf.constructCollectionType(ArrayList.class,type);
objDTOS=objectMapper.readValue(root.traverse(), listOfObjs);
} catch (NullPointerException e) {
Logger.write("Jackson Json List Reader", e.getMessage(), Logger.ERROR);
} catch (JsonParseException e) {
Logger.write("Jackson Json List Reader", e.getMessage(), Logger.ERROR);
} catch (IOException e) {
Logger.write("Jackson Json List Reader", e.getMessage(), Logger.ERROR);
}
return objDTOS;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With