在解析其中一个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"} }
答案 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,那么我们确定有“名称”值。
- 否则,我们需要检查字符串中是否存在“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
答案 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响应。