2013-04-10 15 views
34

Próbuję uzyskać typ wartości przechowywanych w JSONObject.Jak sprawdzić typ wartości z JSONObject?

String jString = {"a": 1, "b": "str"}; 
JSONObject jObj = new JSONObject(jString); 

Czy to możliwe, aby uzyskać typ wartości zapisanej w kluczowym "a"; coś jak jObj.typeOf("a") = java.lang.Integer?

+1

Jeśli chcesz mieć większą kontrolę nad JSON parsowania, użyć innej składni niż 'org.json', takich jak Jackson. – laalto

Odpowiedz

57

Obiekt można pobrać z JSON przy użyciu metody get(), a następnie za pomocą operatora instanceof sprawdzić typ obiektu. Coś takiego: -

String jString = "{\"a\": 1, \"b\": \"str\"}"; 
JSONObject jObj = new JSONObject(jString); 
Object aObj = jObj.get("a"); 
if(aObj instanceof Integer){ 
    System.out.println(aObj); 
} 
+0

Zauważ, że może to być 'Integer' lub' Long'; 'Float' lub' Double'. – 18446744073709551615

+0

hehe, Mam pewien mityczny przykład dla tej sprawy: Mam dwa takie same JSONObject {"wizyty": 4880502, ...}, ale kiedy otrzymam to pole przez object.get ("wizyty") mam: object1 val: 4880502.0 | klasa java.lang.Double object2 val: 4880502 | klasa java.lang.Integer –

+0

Czy gson ma podobną funkcjonalność? Ich dokumentacja nie wydaje się niczego określać w odniesieniu do uzyskania typu określonego pola. –

9

Najlepszym rozwiązaniem jest użycie JSONObject.get() i sprawdzenie typu za pomocą operatora instanceof.

+0

Możesz użyć tego rodzaju podejścia do każdego potrzebnego typu, wychwytując odpowiednie wyjątki. –

+0

Pierwsze podejście, wyjątek wyrzucania, jest kosztowne pod względem zasobów i powinno być unikane, szczególnie jeśli jest używane na urządzeniach krytycznych dla zasobów. (mobile/tabs) – Ankit

+0

@ ay89 thanx! naprawione. – BobTheBuilder

0

można analizować wszystkie dane jak String a następnie spróbuj przekonwertować go do żądanego typu. W tym momencie możesz wychwycić wyjątek i określić, który typ jest sparsowanymi danymi.

2

Uwaga JSONObject.get() może zwrócić liczbę całkowitą albo jako java.lang.Integer lub java.lang.Long, na przykład, dla {a:3,b:100300000000} widzimy

D/+++  (5526): +++a=>class java.lang.Integer:3 
D/+++  (5526): +++b=>class java.lang.Long:100300000000 

użyć kodu podobnego (zauważmy, że używamy rodzajów long i double zamiast int i float, a moim zadaniem nie może być nie zagnieżdżony JSONObject lub JSONArray więc oni nie są obsługiwane):

for (String k : new AsIterable<String>(json.keys())) { 
      try { 
        Object v = json.get(k); 
     //Log.d("+++","+++"+k+"=>"+v.getClass()+":"+v); 
        if (v instanceof Integer || v instanceof Long) { 
          long intToUse = ((Number)v).longValue(); 
          ... 
        } else if (v instanceof Boolean) { 
          boolean boolToUse = (Boolean)v).booleanValue(); 
          ... 
        } else if (v instanceof Float || v instanceof Double) { 
          double floatToUse = ((Number)v).doubleValue(); 
          ... 
        } else if (JSONObject.NULL.equals(v)) { 
          Object nullToUse = null; 
          ... 
        } else { 
          String stringToUse = json.getString(k); 
          ... 
        } 
      } catch (JSONException e2) { 
        // TODO Auto-generated catch block 
        Log.d("exc: "+e2); 
        e2.printStackTrace(); 
      } 
    } 

gdzie AsIterable pozwala nam korzystać z pętli for(:) z iteratora i jest zdefiniowany jako:

public class AsIterable<T> implements Iterable<T> { 
    private Iterator<T> iterator; 
    public AsIterable(Iterator<T> iterator) { 
     this.iterator = iterator; 
    } 
    public Iterator<T> iterator() { 
     return iterator; 
    } 
} 
+0

Dlaczego ciąg nie jest rzutowany na ciąg znaków i ponownie używasz metody getString? – htafoya