[英]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,则我们确定存在“名称”值。
- 否则,我们需要检查字符串中是否存在“ 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.