我正从服务器中检索一些JSON
数据。有时,这可以以JSONObject
(一个对象)或JSONArray
(多个对象)的形式出现。我知道如何检测如果它是一个数组或一个对象......但问题是检测它意味着我必须有两个完全独立的逻辑位,一个用于对象和一个用于数组。这是一个非常不洁净的解决方案,我很惊讶,不会经常被问到这个问题。
我想做的是:如果JSON
是JSONObject
(一个对象),则将其转换为JSONArray
(只有一个条目)。然后我可以继续我的常规逻辑来解释JSONArray
s。
我的JSON
会像这样进来:
{
"Changes":
{
"Row":
{
"@ChangeId":"17192386","@Type":"U","@TableName":"Change","@PK":"g1fbb6c7-abcf-e741-846c-b499baf5845d","@ColList":"date"
},
"Data":
{
"@date":"22/05/2014 09:03:00"
}
}
}
通常我在Row
和Data
个对象中有多条记录。但在这种情况下,我每个只有一个。我通常的方法是:
JSONObject jsonObj = new JSONObject(jsonString);
JSONObject changes = jsonObj.getJSONObject("Changes");
JSONArray arrChanges = changes.getJSONArray("Row");
JSONArray arrData = changes.getJSONArray("Data");
// Cycle through arrays here
此代码将在.getJSONArray("Row");
行崩溃。
为了避免这种情况,在我拥有changes
对象后,我想强制Row
和Data
个对象加入JSONArray
,即使只有{{1}}一个值 - 如上所述,所以我可以继续我的正常逻辑。有没有办法做到这一点?
答案 0 :(得分:6)
使用此方法将JSONObject
转换为JSONArray
:
JSONObject jsonObj = new JSONObject(jsonString);
JSONObject changes = jsonObj.getJSONObject("Changes");
JSONArray arrChanges = covertJsonObjectToJsonArray(changes.get("Row"));
JSONArray arrData = covertJsonObjectToJsonArray(changes.get("Data"));
public JSONArray covertJsonObjectToJsonArray(Object InsideArray) {
JSONArray jsonArray;
if (InsideArray instanceof JSONArray) {
jsonArray = (JSONArray) InsideArray;
} else {
jsonArray = new JSONArray();
jsonArray.put((JSONObject) InsideArray);
}
return jsonArray;
}
如果有JSONArray
,那么它会返回JSONArray
,如果JSONOject
仍然会返回JSONArray
。
答案 1 :(得分:2)
如果我理解你的问题是什么:
JSONObject jsonObj = new JSONObject(jsonString);
JSONObject changes = jsonObj.getJSONObject("Changes");
JSONArray arrChanges = null;
JSONArray arrData = null;
if (isASingleJson) {
arrChanges = new JSONArray();
arrData = new JSONArray();
arrChanges.put(changes.getJSONObject("Row"));
arrData.put(changes.getJSONObject("Data"));
} else {
arrChanges = changes.getJSONArray("Row");
arrData = changes.getJSONArray("Data");
}
//logic to handle arrays here...
答案 2 :(得分:0)
当您创建JSON时,您应该始终创建一个“行”项目数组,即使您只有一个。这样您就不必改变任何逻辑。
希望有所帮助
答案 3 :(得分:0)
在Json数组上创建, 当来自服务器的数据是数组时,则使用相同的流程 但是如果以对象格式从服务器获取数据,则只需创建对象并将该对象再次添加到同一个数组中 所以你需要编写逻辑来解析任何一种情况下的数组。
我希望你明白我的观点。 快乐的Coddddiiiing:)
答案 4 :(得分:0)
感谢AMC的回答,我构建了以下方法来创建JSON对象,将其存储在Android设备上的文件中。然后,如果只存储了一个对象,则读取文件方法在读取时使用convertJsonObjectToJsonArray将其转换回数组。
public void createFile(View v) throws IOException, JSONException {
JSONArray tours = new JSONArray();
JSONObject tour;
tour = new JSONObject();
tour.put("name", "Sea and sand");
tour.put("price", 999);
tours.put(tour);
String text = tour.toString();
FileOutputStream fos = openFileOutput("tours", MODE_PRIVATE);
fos.write(text.getBytes());
fos.close();
UIHelper.displayText(this, R.id.textView1, "File written to disk:\n"+text);
}
public void readFile(View v) throws IOException, JSONException {
// read file to Buffered input stream
FileInputStream fis = openFileInput("tours");
BufferedInputStream bis = new BufferedInputStream(fis);
StringBuffer b = new StringBuffer();
while (bis.available() != 0) {
char c = (char) bis.read();
b.append(c);
}
bis.close();
fis.close();
// deserialize JSON object to text
JSONObject tours = new JSONObject(b.toString());
// If a single object is returned convert it to an Array
JSONArray toursArray = convertJsonObjectToJsonArray(tours);
StringBuilder text = new StringBuilder();
for (int i = 0; i < toursArray.length(); i++) {
String tour = toursArray.getJSONObject(i).getString("name");
text.append(tour).append("\n");
}
UIHelper.displayText(this, R.id.textView1, text.toString());
}
public JSONArray convertJsonObjectToJsonArray(Object InsideArray) {
JSONArray jsonArray;
if (InsideArray instanceof JSONArray) {
jsonArray = (JSONArray) InsideArray;
} else {
jsonArray = new JSONArray();
jsonArray.put((JSONObject) InsideArray);
}
return jsonArray;
}