Java - 解析JSON响应 - 内容是String或JSONObject

时间:2013-08-06 05:36:04

标签: java android json

在解析其中一个Service调用的JSON Response时,我面临一个典型的场景。

其中一个属性的内容(以下示例,将“name”视为属性)作为String或JSONObject。

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

示例:

  

字符串响应

     

{"name":"Adam"}

     

JSON响应

     

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

     

OR

     

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

     

OR

     

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

4 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:2)

将您的响应JSON解析为JSONObject,然后为“name”键获取另一个JSONObject,如果它抛出JSONException,那么您的对象可能是一个String in case,您可以调用get String获取您的“name”键抓住了。

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。 (如果没有,那么你有一个错误,因为你不期望一个数组或数字或null或其他任何东西......)

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

答案 2 :(得分:1)

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

在我的解决方案中,在JSON错误之前,没有任何例外解雇。我正在做的是跟随。

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

只需浏览此代码段,您就会找到问题的解决方案。

// 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

答案 3 :(得分:1)

我也面临这样的问题。我不想手动解析JSON。如果 firstName 存在,请执行此操作,否则执行此操作。我不想弄乱我的结构,因为我只定义了java对象,而我的客户端处理解析。所以,我想出了以下内容:

@Getter
@Setter
@ToString
class Response {
    private Name name;

    @Getter
    @Setter
    @NoArgsConstructor
    @ToString
    public static class Name {
        private String name;
        private String firstName;
        private String middleName;
        private String lastName;

        public Name(String name) {
            this.name = name;
        }
    }
}

然后,解析json;

ObjectMapper objectMapper = new ObjectMapper();
Response response = objectMapper.readValue(json, Response.class);

现在,可以使用相同的类解析字符串响应和JSON响应。