2016-03-23 214 views
20

我知道這不是第一次有人問這個問題,但用Retrofit2我無法找到正確的解決方案來解決我的問題。我遵循一個在線教程,它工作得很好。當我將相同的代碼應用到我自己的端點時,出現以下異常:java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $我不知道如何解決此問題。

接口:

public interface MyApiService { 

// Is this right place to add these headers? 
@Headers({"application-id: MY-APPLICATION-ID", 
     "secret-key: MY-SECRET-KEY", 
     "application-type: REST"}) 
@GET("Music") 
Call<List<Music>> getMusicList(); 



Retrofit retrofit = new Retrofit.Builder() 
     .baseUrl(MySettings.REST_END_POINT) 
     .addConverterFactory(GsonConverterFactory.create()) 
     .build(); 
} 

客戶端代碼:

MyApiService service = MyApiService.retrofit.create(MyApiService.class); 
Call<List<Music>> call = service.getMusicList(); 
call.enqueue(new Callback<List<Music>>() { 

    @Override 
    public void onResponse(Call<List<Music>> call, Response<List<Music>> response) { 
     Log.e("MainActivity", response.body(). 
    } 

    @Override 
    public void onFailure(Call<List<Music>> call, Throwable t) { 
     Log.e("MainActivity", t.toString()); 
    } 
}); 

此代碼這個有效載荷的工作:

[ 
{ 
    "login": "JakeWharton", 
    "id": 66577, 
    "avatar_url": "https://avatars.githubusercontent.com/u/66577?v=3", 
    "gravatar_id": "", 
    "url": "https://api.github.com/users/JakeWharton", 
    "html_url": "https://github.com/JakeWharton", 
    "followers_url": "https://api.github.com/users/JakeWharton/followers", 
    "following_url": "https://api.github.com/users/JakeWharton/following{/other_user}", 
    "gists_url": "https://api.github.com/users/JakeWharton/gists{/gist_id}", 
    "starred_url": "https://api.github.com/users/JakeWharton/starred{/owner}{/repo}", 
    "subscriptions_url": "https://api.github.com/users/JakeWharton/subscriptions", 
    "organizations_url": "https://api.github.com/users/JakeWharton/orgs", 
    "repos_url": "https://api.github.com/users/JakeWharton/repos", 
    "events_url": "https://api.github.com/users/JakeWharton/events{/privacy}", 
    "received_events_url": "https://api.github.com/users/JakeWharton/received_events", 
    "type": "User", 
    "site_admin": false, 
    "contributions": 741 
}, 
{.... 

但不是這一個:

{ 
"offset": 0, 
"data": [ 
    { 
     "filename": "E743_1458662837071.mp3", 
     "created": 1458662854000, 
     "publicUrl": "https://api.backendless.com/dbb77803-1ab8-b994-ffd8-65470fa62b00/v1/files/music/E743_1458662837071.mp3", 
     "___class": "Music", 
     "description": "", 
     "likeCount": 0, 
     "title": "hej Susanne. ", 
     "ownerId": "E743756F-E114-6892-FFE9-BCC8C072E800", 
     "updated": null, 
     "objectId": "DDD8CB3D-ED66-0D6F-FFA5-B14543ABC800", 
     "__meta": "{\"relationRemovalIds\":{},\"selectedProperties\":[\"filename\",\"created\",\"publicUrl\",\"___class\",\"description\",\"likeCount\",\"title\",\"ownerId\",\"updated\",\"objectId\"],\"relatedObjects\":{}}" 
    }, 
    {... 

我的音樂類:

public class Music { 

    private String ownerId; 
    private String filename; 
    private String title; 
    private String description; 
    private String publicUrl; 
    private int likeCount; 

    // Getters & Setters 

} 
+1

看看[這裏](http://stackoverflow.com/questions/35956104/how-to-handle-object-on-onresponse-of-retrofit-2-0/35956131#35956131)。你需要返回一個不同的類,其中包含一個'List 數據' – Blackbelt

+1

它期望一個數組,你給它一個對象 –

+0

謝謝@Blackbelt和TimCastelinjs。現在正在工作。 – oxyt

回答

33

當你說「這個代碼正在與該有效載荷:......但不是這一個:......」這是預期的,這就是它是如何想的工作。實際上,錯誤消息告訴你,在將json轉換爲java對象時,調用期望json中的數組,但是卻得到了一個對象。

這一呼籲:

@GET("Music") 
Call<List<Music>> getMusicList(); 

預計Music對象的列表,這就是爲什麼它與JSON的工作原理:

[ 
    { 
    "login": "JakeWharton", 
    ... 
    }, 
    ... 
] 

因爲JSON本身是你Music對象的數組(改造能在json數組之間轉換爲java列表)。對於第二個json,你只有一個對象而不是數組(注意缺少[...])。爲此,您需要使用映射到該json的另一個模型創建另一個調用。假設您已命名模型MusicList。這裏的調用可能什麼樣子:

@GET("Music") 
Call<MusicList> getMusicList(); 

(請注意,如果您想保留兩個第一個呼叫,這一次,你可能需要更改的方法名)。

MusicList模型可以是這個樣子:

public class MusicList { 
    @SerializedName("data") 
    private List<Music> musics; 
    // ... 
} 

我假設data陣列Music對象的列表,但我也注意到,在jsons是完全不同的。您可能還需要適應此情況,但我認爲您可以在此處找到照片。

+3

謝謝澄清! – oxyt

+2

感謝您的支持 –

+1

謝謝! :) –

0
private List<Message> messages = new ArrayList<>(); 

private void getInbox() { 
     ApiInterface apiService = 
       ApiClient.getClient().create(ApiInterface.class); 

     Call<List<Message>> call = apiService.getInbox(); 
     call.enqueue(new Callback<List<Message>>() { 
      @Override 
      public void onResponse(Call<List<Message>> call, Response<List<Message>> response) { 
       // clear the inbox 
       messages.clear(); 

       // add all the messages 
//     messages.addAll(response.body()); 

       // TODO - avoid looping 
       // the loop was performed to add colors to each message 

       mAdapter.notifyDataSetChanged(); 
       swipeRefreshLayout.setRefreshing(false); 
      } 

      @Override 
      public void onFailure(Call<List<Message>> call, Throwable t) { 
       Toast.makeText(getApplicationContext(), "Unable to fetch json: " + t.getMessage(), Toast.LENGTH_LONG).show(); 
      } 
     }); 
    } 


import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 

public class ApiClient { 
    public static final String BASE_URL = "http://api.androidhive.info/json/"; 
    private static Retrofit retrofit = null; 

    public static Retrofit getClient() { 
     if (retrofit == null) { 
      retrofit = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 
     } 
     return retrofit; 
    } 
} 


import com.keshav.gmailretrofitexampleworking.models.Message; 

import java.util.List; 

import retrofit2.Call; 
import retrofit2.http.GET; 

public interface ApiInterface { 
    @GET("inbox.json") 
    Call<List<Message>> getInbox(); 
} 

======================================================= 
package com.keshav.gmailretrofitexampleworking.models; 

public class Message { 
    private int id; 
    private String from; 
    private String subject; 
    private String message; 
    private String timestamp; 
    private String picture; 
    private boolean isImportant; 
    private boolean isRead; 
    private int color = -1; 

    public Message() { 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getFrom() { 
     return from; 
    } 

    public void setFrom(String from) { 
     this.from = from; 
    } 

    public String getSubject() { 
     return subject; 
    } 

    public void setSubject(String subject) { 
     this.subject = subject; 
    } 

    public String getMessage() { 
     return message; 
    } 

    public void setMessage(String message) { 
     this.message = message; 
    } 

    public String getTimestamp() { 
     return timestamp; 
    } 

    public void setTimestamp(String timestamp) { 
     this.timestamp = timestamp; 
    } 

    public boolean isImportant() { 
     return isImportant; 
    } 

    public void setImportant(boolean important) { 
     isImportant = important; 
    } 

    public String getPicture() { 
     return picture; 
    } 

    public void setPicture(String picture) { 
     this.picture = picture; 
    } 

    public boolean isRead() { 
     return isRead; 
    } 

    public void setRead(boolean read) { 
     isRead = read; 
    } 

    public int getColor() { 
     return color; 
    } 

    public void setColor(int color) { 
     this.color = color; 
    } 
} 

======================================= 
Response 
========================================= 
[ 
    { 
     "id": 1, 
     "isImportant": false, 
     "picture": "http://api.androidhive.info/json/google.png", 
     "from": "Google Alerts", 
     "subject": "Google Alert - android", 
     "message": "Now android supports multiple voice recogonization", 
     "timestamp": "10:30 AM", 
     "isRead": false 
    }, 
    { 
     "id": 2, 
     "isImportant": true, 
     "picture": "", 
     "from": "Amazon.in", 
     "subject": "Apple Macbook Pro", 
     "message": "Your Amazon.in Today's Deal Get Macbook Pro", 
     "timestamp": "9:20 AM", 
     "isRead": false 
    }, 
    { 
     "id": 3, 
     "isImportant": false, 
     "picture": "http://api.androidhive.info/json/imdb.png", 
     "from": "IMDB", 
     "subject": "Check out top rated movies this week", 
     "message": "Find out the top rated movies this week by editor choice", 
     "timestamp": "9:15 AM", 
     "isRead": false 
    }, 
    { 
     "id": 4, 
     "isImportant": false, 
     "picture": "https://scontent-frt3-1.xx.fbcdn.net/v/t1.0-1/p160x160/16298485_10208198778434887_8511207535440105240_n.jpg?oh=37c747b74709ff3bbdec6102c189cea5&oe=5929B733", 
     "from": "Dinesh Reddy, Me", 
     "subject": "Let's get started", 
     "message": "I started working on project proposals. Wanted to know", 
     "timestamp": "9:00 AM", 
     "isRead": true 
    }, 
    { 
     "id": 5, 
     "isImportant": false, 
     "picture": "", 
     "from": "BookMyShow", 
     "subject": "Will the lost boy find his family?", 
     "message": "LION a movie that humanity needs. Online version report spam 97%", 
     "timestamp": "8:55 AM", 
     "isRead": false 
    }, 
    { 
     "id": 6, 
     "isImportant": false, 
     "picture": "", 
     "from": "MakeMyTrip", 
     "subject": "A joyous Train Ride in North East!", 
     "message": "North East Package starting from Rs31,999/- only!", 
     "timestamp": "8:10 AM", 
     "isRead": false 
    }, 
    { 
     "id": 7, 
     "isImportant": false, 
     "picture": "", 
     "from": "Disqus 14", 
     "subject": "Re: Comment on Android Working with", 
     "message": "Hey Ravi, after following your article I am getting this error", 
     "timestamp": "8:10 AM", 
     "isRead": true 
    }, 
    { 
     "id": 8, 
     "isImportant": true, 
     "picture": "", 
     "from": "Evans, Ravi 3", 
     "subject": "Advertisement Enquiry", 
     "message": "Hello, I want to buy the advertising space on", 
     "timestamp": "7:59 AM", 
     "isRead": false 
    }, 
    { 
     "id": 9, 
     "isImportant": false, 
     "picture": "https://lh3.googleusercontent.com/9JKVlFDCj9VVIbI66z_JEXGXvQpUXc-EwXfDmYP9c-8Lwb6Bd_zZ9i6VygPpyXLj3PkNCtpmTvaKKw=w300-h300-rw-no", 
     "from": "Karthik Tamada", 
     "subject": "Call Me", 
     "message": "I am going home because I am not feeling well!", 
     "timestamp": "4:05 AM", 
     "isRead": false 
    }, 
    { 
     "id": 10, 
     "isImportant": false, 
     "picture": "", 
     "from": "Order-Update", 
     "subject": "Your Amazon order #408-2878882019", 
     "message": "Your Orders | Amazon.in shipment of pendrive", 
     "timestamp": "5:00 AM", 
     "isRead": true 
    }, 
    { 
     "id": 11, 
     "isImportant": false, 
     "picture": "", 
     "from": "Instapage", 
     "subject": "Lead notification from Instapage", 
     "message": "Congratulations! You just aquired a new lead", 
     "timestamp": "3:00 AM", 
     "isRead": false 
    }, 
    { 
     "id": 12, 
     "isImportant": false, 
     "picture": "", 
     "from": "Droid5", 
     "subject": "Droid5 Android Project", 
     "message": "Planning to start an android app for droid5", 
     "timestamp": "5:00 AM", 
     "isRead": false 
    }, 
    { 
     "id": 13, 
     "isImportant": true, 
     "picture": "", 
     "from": "Gmail Team", 
     "subject": "Gmail Business Suite", 
     "message": "Your Gmail business suite is expiring today!", 
     "timestamp": "Feb 20", 
     "isRead": true 
    }, 
    { 
     "id": 14, 
     "isImportant": false, 
     "picture": "", 
     "from": "Medium Daily Digest", 
     "subject": "6 Things You need to know to Recover", 
     "message": "Daily Digest Your daily three recommendations", 
     "timestamp": "8:15 AM", 
     "isRead": false 
    }, 
    { 
     "id": 15, 
     "isImportant": false, 
     "picture": "", 
     "from": "Alex, Ravi 24", 
     "subject": "Advertisement proposal to promote my android app", 
     "message": "Hello Ravi, Thanks for your link. Here is the proposal", 
     "timestamp": "Feb 17", 
     "isRead": false 
    } 
] 
+0

調用<列表> getInbox(); –

相關問題