繁体   English   中英

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

[英]Java - Parsing JSON Response - Content is either String or JSONObject

我在解析其中一个Service调用的JSON Response时遇到一种典型情况。

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

如何通过代码处理此类情况。 另外,请考虑json内容不必与同一组属性一致。

例:

字符串响应

{"name":"Adam"}

JSON回应

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

OR

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

OR

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

您可以使用optJSONObject(name)方法要求根JSONObject返回给定名称的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
}

将您的响应JSON解析为JSONObject,然后为“ name”键获取另一个JSONObject,如果它抛出JSONException,则您的对象可能是String,以防万一,您可以在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。 (如果两者都不是,则您将遇到错误,因为您不希望使用数组或数字或null或其他任何内容...)

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

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

我也遇到这样的问题。 我不想手动解析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响应。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM