我正在尝试反序列化(使用gson)如下所示的JSON对象:
"attachments": { "40": { "ID": 40, "URL": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/wreckit.jpg", "guid": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/wreckit.jpg", "mime_type": "image\/jpeg", "width": 287, "height": 400 }, "3": { "ID": 3, "URL": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/frankenweenie2bposter.jpg", "guid": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/frankenweenie2bposter.jpg", "mime_type": "image\/jpeg", "width": 273, "height": 400 } },
我该如何处理?我什至不知道该怎么称呼- 这里代表了多个“项目”,但这不是一个数组。当我尝试将其反序列化为数组时,程序在“预期的Begin_Array但找到Begin_Object”异常时崩溃。当我尝试将其反序列化为Strong对象时(请参见下面的类),程序将运行,但所有字段均返回null。
这是我尝试将其映射到的类:
class Attachment { int ID; String URL; }
完整的JSON文件可以在这里看到 :
编辑:已解决。
@Perception的解决方案基本有效。这个“元素”(仍然想知道这个多入口/非数组json元素是什么)被嵌入在一个确实包含数组的更大的json对象中的事实使情况变得复杂。再说一次,这个JSON不是我设计的- 它来自Wordpress REST API,并且(正如@Perception所暗示的那样),我认为我遇到的问题说明了它的设计缺陷- 也就是说,attachments元素应该是一个数组,而不是单个对象。尽管如此,
但是,如果其他任何人需要使用此API对给定站点上所有帖子的查询结果进行反序列化,并且进一步需要访问每个帖子的附件,请按以下步骤操作:
private class getAll extends AsyncTask <Void, Void, JSONObject> { private static final String url = "https://public-api.wordpress.com/rest/v1/sites/drewmore4.wordpress.com/posts/"; @Override protected JSONObject doInBackground(Void... params) { HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet(url); httpget.addHeader("accept", "application/json"); JSONObject returned = new JSONObject(); HttpResponse response; try { response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); String result= convertStreamToString(instream); returned =new JSONObject(result); instream.close(); } } catch (ClientProtocolException | IOException | JSONException e) { e.printStackTrace();} return returned; } @Override protected void onPostExecute (JSONObject returned){ Gson gson = new Gson(); //posts is the element within the JSONObject that is an array of post objects try { JSONArray posts = returned.getJSONArray("posts"); for (int curr = 0; curr < posts.length(); curr++){ String s = posts.get(curr).toString(); Article a = gson.fromJson(s, Article.class); JSONObject attachments = new JSONObject(s).getJSONObject("attachments"); final Iterator<String> keys = attachments.keys(); while(keys.hasNext()) { final String key = keys.next(); a.attached.add(gson.fromJson(attachments.getJSONObject(key).toString(), Attachment.class)); } stories.add(a); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); }
这是一个数据示例,可能 应该 已经序列化为数组,但是没有被序列化。解析它的一种解决方案是JSONObject直接利用Direct。
JSONObject
String json = ...; final Gson gson = new Gson(); final List<Attachment> attachements = new ArrayList<Attachment>(64); final JSONObject jsonObj = new JSONObject(json).getJSONObject("attachments"); final Iterator<String> keys = jsonObj.keys(); while(keys.hasNext()) { final String key = keys.next(); attachements.add(gson.fromJson(jsonObj.getJSONObject(key).toString(), Attachment.class); } // Do something with attachements
该数据 可 也被看作是一个地图,ID的对附件。可以这样反序列化:
final String jsonObj = new JSONObject(json).getJSONObject("attachments"); final Gson gson = new Gson(); final Map<String, Attachment> data = gson.fromJson(jsonObj.toString(), new TypeToken<Map<String, Attachment>>() { }.getType()); final List<Attachment> attachments = new ArrayList<Attachment>(data.values());
这是实际的