Java 反序列化包含多个项目的JSON对象
我正在尝试反序列化(使用gson)一个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
"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());