2013-08-06 51 views
0

我在解析某个服务调用的JSON响应时遇到了一个典型场景。Java - 解析JSON响应 - 内容是字符串或JSONObject

其中一个属性的内容(来自下面的示例,将“name”视为属性)以String或JSONObject形式出现。

如何通过代码处理这些场景。另外,请考虑json内容不需要与同一组属性保持一致。

实施例:

字符串响应

{"name":"Adam"}

JSON响应

{"name":{"FirstName":"Adam", "MiddleName":"Don"} }

OR

{"name":{"FirstName":"Adam", "LastName":"Don"} }

OR

{"name":{"MiddleName":"Adam", "LastName":"Don"} }

+0

所以..你要解析JSON字符串在java中? – codeMan

+1

在上面的例子中,每个都是JSON ..你怎么说'{“name”:“Adam”}'是字符串 –

+0

你到底在找什么?你的问题不清楚 –

回答

2

解析您的响应JSON作为一个JSONObject,然后再弄的JSONObject的 “姓名” 键,如果它抛出一个JSONException那么你的对象可能是一个字符串,你可以在你的catch块中为“name”键调用get String。

String name = ""; 
JSONObject serverJSON = new JSONObject(YOUR_JSON_RESPONSE_STRING_FROM_SERVER); 

try { 
    JSONObject nameObject = serverJSON.getJSONObject("name"); 
    if (nameObject.has("first_name")) { 
     name = nameObject.getString("first_name") + " "; 
    } 

    if (nameObject.has("middle_name")) { 
     name += nameObject.getString("middle_name") + " "; 
    } 

    if (nameObject.has("last_name")) { 
     name += nameObject.getString("last_name"); 
    } 

    name = name.trim(); 
} catch (JSONException e) { 
    // Probably a String, try again... 
    try { 
      name = serverJSON.getString("name"); 
    catch (JSONException e) { 
      // Not a String or a JSONObject... figure out what's wrong... 
      e.printStackTrace(); 
    } 
} 

我真的建议虽然,如果您有确保的名称键选择一种类型,坚持在服务器的任何控制;一个JSONObject ...你可以在if语句中使用has(String key)成员函数在不知道运行时存在什么的情况下正确找到所有数据...

编辑:想到另一种想法。 ..解析字符串到第一个冒号,看看下一个非空白字符是否是一个引号,如果是,那么你的密钥属于一个字符串,如果它是一个大括号,那么它是一个JSONObject。 (如果没有,那么你有一个错误,因为你不期待一个数组或号码或空或其他任何东西......)

boolean jsonIsString = true; 
String searchString = json.substring(json.indexOf(":")).trim(); 
if ("{".equals(searchString.charAt(0)) { 
    jsonIsString = false; 
} 
3

你可以问根JSONObject与方法optJSONObject(name)返回一个JSONObject对于给定的名称,如果它存在并且是JsonObject。否则,您也可以使用optString(name)测试字符串。

因此,像:

JSONObject root = new JSONObject(... data from server ...); 
JSONObject obj = root.optJSONObject("name"); 
if (obj != null) { 
    // Do something with the object 
} else { 
    String name = root.getString("name"); 
    // Do something with the string 
} 
+0

完全不了解可选方法...更加优雅。 +1 – Tonithy

1

Tonity的解决方案是好的。您也可以使用此解决方案。

在我的解决方案中,不会有任何异常开除直到JSON出错。我正在做的是跟随。

  1. 在字符串中搜索“:”的数量。
  2. 如果它返回1,那么我们确定有“名称”值。
  3. 否则,我们需要检查字符串中是否存在“FirstName”,“MiddleName”或“LastName”。

只要通过这个片段,你会发现你的问题的解决方案。

// String str = "{\"name\":\"chintan\"}"; 
String str = "{\"name\":{\"FirstName\":\"Chintan\",\"LastName\":\"Rathod\"}}"; 

try { 
    //we will check how many ":" are there in string, if it is one, then 
    // we are going to get "name" field. 
    if ((str.split(":").length - 1) == 1) 
    { 
     Log.d("Home", "1"); 
     JSONObject json = new JSONObject(str); 
     Log.d("Home", "Name : " + json.get("name")); 
    } 
    else 
    { 
     Log.d("Home", "more then 2"); 

     JSONObject jName = new JSONObject(str); 

     JSONObject jTemp = jName.getJSONObject("name"); 

     if (jTemp.toString().contains("FirstName")) 
      Log.d("Home", "FirstName :" + jTemp.getString("FirstName")); 

     if (jTemp.toString().contains("MiddleName")) 
      Log.d("Home","MiddleName :" +jTemp.getString("MiddleName")); 

     if (jTemp.toString().contains("LastName")) 
      Log.d("Home", "LastName :" + jTemp.getString("LastName")); 
    } 
} catch (JSONException e) { 
    e.printStackTrace(); 
} 

输出

08-06 11:52:34.060: D/Home(1439): more then 2 
08-06 11:52:34.060: D/Home(1439): FirstName :Chintan 
08-06 11:52:34.070: D/Home(1439): LastName :Rathod