2013-02-25 7 views
7

Tôi đang cố gắng để deserialize (sử dụng gson) một đối tượng JSON trông như thế này:deserializing một đối tượng JSON với nhiều mục bên trong nó

 "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 
      } 
    }, 

Làm thế nào để xử lý nó? Tôi thậm chí không biết phải gọi cái gì - Có nhiều "mặt hàng" đại diện ở đây, nhưng nó không phải là một mảng. Khi tôi cố gắng deserialize nó như là một mảng, chương trình bị treo trên một "Mong đợi Begin_Array nhưng tìm thấy Begin_Object" ngoại lệ. Khi tôi cố gắng deserialize nó như là một đối tượng mạnh mẽ (xem lớp dưới đây), chương trình chạy nhưng các lĩnh vực tất cả trở về null.

Đây là lớp tôi đã cố gắng để ánh xạ nó vào:

class Attachment { 
int ID; 
String URL; 
} 

file JSON đầy đủ có thể được nhìn thấy here:

EDIT: SOLVED.

@ Giải pháp của nhận thức về cơ bản đã hoạt động. Nó phức tạp bởi thực tế là "phần tử" này (vẫn muốn biết phần tử json nhiều mục/non-array này) được nhúng vào trong một đối tượng json lớn hơn có chứa một mảng. Một lần nữa, JSON này không phải là thiết kế của tôi - nó xuất phát từ API REST của Wordpress, và (như @Perception ám chỉ), tôi nghĩ vấn đề tôi đã minh họa một lỗ hổng thiết kế trong nó - cụ thể là phần tử phần đính kèm phải là một mảng , chứ không phải là một đối tượng duy nhất. Tuy nhiên,

Tuy nhiên, nếu bất kỳ ai khác cần xóa kết quả truy vấn cho tất cả các bài đăng trên một trang web nhất định bằng API này và cần truy cập vào các tệp đính kèm trên mỗi bài đăng, dưới đây là cách bạn thực hiện:

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(); 
      } 

Trả lời

7

Đây là ví dụ về dữ liệu có thể là nên đã được tuần tự hóa thành một mảng nhưng không được. Một giải pháp để phân tích cú pháp đó là sử dụng trực tiếp 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 

Dữ liệu thể cũng được xem như là một bản đồ, các id để đính kèm. Và nó có thể được deserialized như vậy:

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()); 

Đây là actuall

+0

Tôi nghĩ rằng có một sự hiểu lầm ở đây, về phía tôi hoặc của bạn. Những gì đang được đại diện ở đây không phải là các bài viết, nhưng các thành phần của bài viết (cụ thể là các phần đính kèm) mà tôi đang cố gắng deserialize vào các trường của các cá thể bài viết mà bạn đã giúp tôi trước đây .. – drewmoore

+0

@ drewmore4 - thực sự. Kiểm tra chỉnh sửa của tôi (không có gì đáng kể, về cơ bản thay thế 'Điều' bằng' Đính kèm'). – Perception

+0

Đó là những gì tôi figured :) Tôi đang cố gắng những gì bạn đề nghị nhưng đang nhận được một cảnh báo lỗi - Chỉ có thể lặp qua một mảng hoặc một thể hiện của java.lang.Iterable - trên vòng lặp for. – drewmoore

2

Đầu tiên tạo JSONArray từ JSONObject này., sau đó

for(int i = 0; i < contacts.length(); i++){ 
      JSONObject c = contacts.getJSONObject(i); 

Bằng việc sử dụng vòng lặp này được các giá trị chuỗi và đưa vào bản đồ hoặc đối tượng mà u muốn và thêm nó vào một ArrayList

HashMap<String, String> map = new HashMap<String, String>(); 

      // adding each child node to HashMap key => value 
      map.put(TAG_ID, id); 

contactList.add(map); 

sau đó bạn có thể sử dụng các giá trị.

0

Làm thế nào để xử lý nó? Tôi thậm chí không biết phải gọi cái gì - Có nhiều "mặt hàng" đại diện ở đây, nhưng nó không phải là một mảng.

Dường như bộ sưu tập trong JSON là sự phù hợp tự nhiên cho java.util.map. Vì vậy, tôi có lẽ sẽ deserialize JSON "file đính kèm" vào một Map<String, Atachment>. Bản đồ sau đó dễ dàng lặp lại hoặc chuyển đổi tập hợp các giá trị Đính kèm thành một loại bộ sưu tập khác, chẳng hạn như List<Attachment> hoặc Attachment[].

Lưu ý: The Gson User Guide bao gồm ví dụ về cách sắp xếp lại thành Bộ sưu tập chung.