2012-07-16 15 views
12

Używam Jackson 1.9.5 w projekcie Android do parsowania plików JSON.Jackson ObjectMapper z arbitralnymi kluczami JSON

Do tej pory nie miałem żadnych problemów, a może analizować pliki grzywny za pomocą następującego kodu:

AssetManager mgr = getAssets(); 
ObjectMapper mapper = new ObjectMapper(); 

try { 
    InputStream ifp = mgr.open("detail_schema.json"); 
    schema = mapper.readValue(ifp, DetailSchema.class); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

gdzie klasa DetailSchema składa się z mieszanki prymitywnych typów i klas. Jestem teraz uruchomiony na problem gdzie chcę analizować niektóre JSON jak poniżej:

"fields": { 
    "Suburb": "Paddington", 
    "State": "NSW", 
    "Post Code": "2074", 
    "Lollipop": "Foo Bar Haz" 
} 

gdzie nie może wiedzieć klawiszy mapy przed dłoni (mogą być definiowane przez użytkownika). W związku z tym nie jestem pewien, jak powinna wyglądać powiązana klasa Java.

Ie, na ten przykład, może to wyglądać tak:

public class MyClass { 

    public String Suburb; 
    public String State; 
    public String PostCode; 
    public String Lollipop; 

} 

Ale może to nie być odpowiednie dla innej instancji pliku JSON. Idealnie potrzebuję jakiegoś sposobu, aby Jackson wyznaczył wartości na coś w rodzaju NameValuePair. Podejrzewam, że automatyczne mapowanie obiektów może nie być w tym przypadku możliwe - czy ktoś może to potwierdzić lub zaprzeczyć?

Odpowiedz

16

Masz dwie opcje. Można użyć wartości readTree in ObjectMapper, która zwraca wartość JsonNode. Praca z JsonNode jest bardzo podobny do pracy z drzewem, dzięki czemu można uzyskać dzieci węzły, odczyt wartości, et cetera:

InputStream ifp = mgr.open("detail_schema.json"); 
JsonNode root = mapper.readTree(ifp); 
JsonNode fields = root.get("fields"); 
for (JsonNode children : fields.getElements()) { 
    // ... 
} 

Potem trzeba zbudować swój obiekt DetailSchema ręcznie.

Albo, można pozwolić Jackson deserializowania go jako mapy, w którym to przypadku byłoby użyć kodu ale gdzie MyClass byłoby tak:

public class MyClass { 
    public Map<String, Object> fields; 

    // getter/setters 
} 

Prawdopodobnie można wpisać wartości mapie jako String jako cóż, jeśli jesteś pewien, że dane wejściowe są tekstem w jsonie. (Właściwie to nie jestem pewien, jaki typ egzekucji wykonuje Jackson, może to pozwoli cokolwiek i tak ...)

+1

Wielkie dzięki! Mapa będzie działać dobrze dla moich celów. – aaronsnoswell

+0

Nie musisz używać niestandardowej klasy, aby uzyskać 'Mapę', możesz mieć deserializację Jackson bezpośrednio do implementacji interfejsu' Map', np .: 'Map jsonFields = mapper.readValue (ifp, HashMap .class) ' – brianmearns

Powiązane problemy