Java 反序列化包含多个项目的JSON对象

Java 反序列化包含多个项目的JSON对象,java,android,json,gson,Java,Android,Json,Gson,我正在尝试反序列化(使用gson)一个JSON对象,如下所示: "attachments": { "40": { "ID": 40, "URL": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/wreckit.jpg", "guid": "http:\/\/drewmore4.files.wordpress

我正在尝试反序列化(使用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\u数组但找到Begin\u对象”异常下崩溃。当我尝试将其反序列化为强对象(请参见下面的类)时,程序将运行,但所有字段都返回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();
            }
私有类getAll扩展异步任务{
私有静态最终字符串url=”https://public-api.wordpress.com/rest/v1/sites/drewmore4.wordpress.com/posts/";
@凌驾
受保护的JSONObject doInBackground(无效…参数){
HttpClient HttpClient=新的DefaultHttpClient();
HttpGet HttpGet=新的HttpGet(url);
addHeader(“接受”、“应用程序/json”);
返回的JSONObject=新的JSONObject();
HttpResponse响应;
试一试{
response=httpclient.execute(httpget);
HttpEntity=response.getEntity();
如果(实体!=null){
InputStream instream=entity.getContent();
字符串结果=convertStreamToString(流内);
返回=新的JSONObject(结果);
流内关闭();
}
} 
catch(ClientProtocolException | IOException | jsoneexception e){e.printStackTrace();}
返回;
}
@凌驾
受保护的void onPostExecute(返回JSONObject){
Gson Gson=新的Gson();
//posts是JSONObject中的元素,它是post对象的数组
试一试{
JSONArray posts=returned.getJSONArray(“posts”);
对于(int curr=0;curr
首先从这个JSONObject创建JSONArray。, 然后


然后您可以使用该值。

这是一个数据示例,该数据可能应序列化为数组,但不是。解析该数据的一个解决方案是直接使用
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
stringjson=。。。;
最终Gson Gson=新Gson();
最终列表附件=新的ArrayList(64);
final JSONObject jsonObj=新的JSONObject(json).getJSONObject(“附件”);
final Iterator keys=jsonObj.keys();
while(keys.hasNext()){
最后一个字符串键=keys.next();
add(gson.fromJson(jsonObj.getJSONObject(key.toString(),Attachment.class));
}
//用附件做点什么

数据也可以查看为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());
final String jsonObj=newjsonobject(json).getJSONObject(“附件”);
最终Gson Gson=新Gson();
最终映射数据=gson.fromJson(jsonObj.toString(),
新的TypeToken(){
}.getType());
最终列表附件=新的ArrayList(data.values());
这是事实

我怎么处理它呢?我甚至不知道该怎么称呼它——这里表示了多个“项”,但它不是数组


看起来JSON中的集合非常适合
java.util.map
。因此,我可能会反序列化JSON“附件”进入
映射
。映射很容易迭代,或者将附件值的集合转换为不同类型的集合,例如
列表包含反序列化为通用集合的示例。

我认为这里有一个误解,无论是我的还是你的。这里表示的不是articles,但我正在尝试将文章的组件(即附件)反序列化到您之前帮助我处理的文章实例的字段中。@drewmore4-确实如此。请查看我的编辑(没有实质性内容,基本上用
附件
替换
文章
)。这就是我的想法:)我正在尝试您的建议,但收到一条错误警告-只能在for循环上迭代一个数组或java.lang.Iterable的实例。@drewmore4-已编辑。您可能需要调整代码,我没有访问IDE atm的权限。谢谢。我需要做一些额外的工作,但您的解决方案让我达到了这一点。如果您好奇,请参阅我的编辑
contactList.add(map);
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
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());