2013-07-05 21 views
12

Jestem w trakcie aktualizacji Jacksona z wersji 1.9.4 do wersji 2.2.0. Przejście było płynne, z tym że nie mogę uzyskać analizy parsowania dla obiektów działających. W wersji 1.9.4 mogłem to zrobić:Parsowanie tablicy obiektów JSON przy użyciu pakietu Jackson 2.0

private List<Subjects> mSubjects; 
mSubjects = objectMapper.readValue(subjectsJsonArrayNode, new TypeReference<List<Subjects>>() {}); 

Z wersją 2.2.0 otrzymałem błąd "nie można rozwiązać metody" podczas kompilacji. ObjectMapper plik header Jacksona do 1.9.4 zawiera te readValue metody 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) 

A nagłówek pliku Jackson 2.2.0 za:

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) 

Więc muszę przełączyć się z przechodzącą JsonNode do JsonParser, ale nie jestem całkiem pewien, jak dokonać tego przejścia. To powiedziawszy, nie jestem pewien, czy idę nawet właściwą drogą, ponieważ JsonParser jest zdefiniowany jako klasa abstrakcyjna, więc nie mogę nawet łatwo zainicjować instancji, aby się z nią bawić.

Dla tych, którzy przychodzą bez odpowiedzi, o to rozwiązanie tymczasowe mam w miejscu gdzie iteracji i ręcznie analizować każdy obiekt:

private List<Subjects> mSubjects = new ArrayList<Subjects>(); 
for(JsonNode subjectJsonNode : subjectsJsonArrayNode) { 
    mSubjects.add(objectMapper.treeToValue(subjectJsonNode, Subject.class)); 
} 

Odpowiedz

41

może po prostu wywołać metodę JsonNode.traverse() aby uzyskać JsonParser.

Testowane z następującym prostym przykładzie:

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

wyjścia:

+1

trawers() załatwił sprawę. Wielkie dzięki Brian. Twoje zdrowie! – Mark

+0

nie działają, jeśli klasa Foo ma niestandardowy deserializator – herau

+0

Alternatywnie można użyć wywołania 'ObjectMapper.treeToValue()', zaprojektowanego do robienia tego, co chcesz. – StaxMan

1

używać tej metody do list:

/** 
* 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; 
} 
+0

co to jest getRootName()? i jak sprawić, by był ogólny dla handeliing jakiegokolwiek RootName? –

Powiązane problemy