2013-03-15 16 views
29

Zastanawiam się, czy gdzieś tam istnieje java librery zdolne do zapytania JSONObject. Głębiej szukam czegoś podobnego:Zapytanie o JSONObject w java

String json = "{ data: { data2 : { value : 'hello'}}}"; 

... 
// Somehow we managed to convert json to jsonObject 
... 

String result = jsonObject.getAsString("data.data2.value"); 

System.out.println(result); 

mogę spodziewać się „cześć” jako wyjście.

Do tej pory najszybszym sposobem znalazłem się przy użyciu Gson:

jsonObject.getAsJsonObject("data").getAsJsonObject().get("data2").getAsJsonObject("value").getAsString(); 

To nie jest rzeczywiście łatwe do zapisu i odczytu. Czy jest coś szybciej?

Odpowiedz

16

Przede wszystkim polecam rozważyć powiązanie obiektu JSON.

Ale jeśli otrzymasz arbitralne obiekty JSON i chcesz je przetworzyć w opisany sposób, proponuję połączyć Jackson JSON processor wraz z Apache's Commons Beanutils.

Pomysł jest następujący: Jackson domyślnie przetwarza wszystkie instancje JSON jako instancje java.util.Map, w międzyczasie Commons Beanutils upraszcza dostęp do właściwości obiektów, w tym tablic i map.

więc można go używać coś takiego:

//actually it is a Map instance with maps-fields within 
Object jsonObj = objectMapper.readValue(json, Object.class); 

Object hello = PropertyUtils.getProperty(jsonObj, "data.data2.value") 

System.out.println(hello); //prints hello 
+0

Tak, już wcześniej brałem pod uwagę wiązanie obiektów (i tak właśnie się zwykle podążam). Ale projekt, nad którym pracuję, ma naprawdę duży JSON do zarządzania, a jego struktura zmienia się z upływem czasu. Naprawdę czasochłonne jest śledzenie każdej zmiany przez powiązanie obiektów. Bardzo dziękuję za sugestie :) – Pamput

+1

Czy to działa dla kluczy, które mają "." w nich? Tak jakby jeden klucz był "link.required", a jego węzeł miał coś w rodzaju "number", czy "link.required.number" zadziałałby? – Penman

1

Myślę, że nie ma mowy.

Rozważyć klasy Java

class Student { 
    Subject subject = new Subject(); 
} 

class Subject { 
    String name; 
} 

tutaj, jeśli chcemy uzyskać dostęp do nazwy podmiotu następnie

Student stud = new Student(); 
stud.subject.name; 

We cant nazwę dostępu bezpośrednio, jeśli tak, to nie dostanie prawidłową nazwę tematu. Jak tutaj:

jsonObject.getAsJsonObject("data") 
      .getAsJsonObject() 
      .get("data2") 
      .getAsJsonObject("value") 
      .getAsString(); 

Jeśli chcesz użyć tego samego obiektu jak java następnie użyć

ClassName classObject = new Gson().fromJson(JsonString, ClassName.class); 

ClassName musi mieć wszystkie pola, aby dopasować jsonstring. Jeśli masz jsonobject wewnątrz jsonobject, musisz stworzyć oddzielną klasę, tak jak robię w klasie Student i Subject.

+0

Wiem, jakie jest powiązanie obiektu i zwykle jest to sposób, w jaki postępuję, gdy zarządzam jsonem :) Ale szukałem szybszego sposobu (czasami jest to zbyt czasochłonne zrobienie fasoli dla czegoś naprawdę prostego, jak w przykładzie, który zasugerowałem) . – Pamput

16

Chociaż nie jest dokładnie taka sama, Jackson ma Drzewo modelu reprezentacja podobny do Gson:

JsonNode root = objectMapper.readTree(jsonInput); 
return root.get("data").get("data2").get("value").asText(); 

więc trzeba przemierzać to krok po krok.

EDIT (sierpień 2015)

Tam faktycznie jest obecnie (od Jackson 2.3) wsparcie dla JSON Pointer wyrażeń z Jacksonem.Więc można używać alternatywnie:

return root.at("/data/data2/value").asText(); 
+2

Możesz zmienić 'get' na' path', aby uniknąć wartości null. – Charles

+2

Czy jest coś podobnego w Gson? – SaurabhJinturkar

31

Właśnie niespodziewanie znalazł bardzo ciekawy projekt: JSON Path

JsonPath ma JSON co XPath XML, to prosty sposób, aby wyodrębnić części danego dokumentu .

Z tej biblioteki można zrobić to, czego żądają nawet łatwiejsze, to mój poprzedni sugestia:

String hello = JsonPath.read(json, "$.data.data2.value"); 

System.out.println(hello); //prints hello 

nadziei, że to może być pomocne albo.

+2

Nowa lokalizacja repozytorium dla ścieżki JSON: https://github.com/jayway/JsonPath – Claus

+0

wygląda dokładnie to, czego potrzebujemy, wyjaśnienie przy użyciu próbki jest bardzo przydatne, każdy może dobrze iść z – Jeevanantham