2016-03-23 8 views
20

So che questa non è la prima volta che qualcuno si interroga su questo problema ma con Retrofit2 non riesco a trovare la soluzione giusta al mio problema. Ho seguito un tutorial online e ha funzionato bene. Quando ho applicato lo stesso codice al mio endpoint ottengo questa eccezione: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ Non so come risolverlo.

Interfaccia:

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

Codice Cliente:

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

Questo codice si lavora con questo payload:

[ 
{ 
    "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 
}, 
{.... 

ma non con questo:

{ 
"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\":{}}" 
    }, 
    {... 

La mia classe Musica:

public class Music { 

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

    // Getters & Setters 

} 
+1

uno sguardo [qui] (http://stackoverflow.com/questions/35956104/how-to-handle-object-on-onresponse-of-retrofit-2-0/35956131#35956131). È necessario restituire una classe diversa che contiene un 'Elenco dati' – Blackbelt

+1

Si aspetta un array, gli si assegna un oggetto –

+0

Grazie @Blackbelt e TimCastelinjs. Sta lavorando adesso. – oxyt

risposta

33

Quando si dice "Questo codice sta lavorando con questo payload: ma ... con questo: ..." che si aspetta ed è così che è supponiamo di lavorare. In effetti il ​​messaggio di errore ti dice che durante la conversione di json in un oggetto java la chiamata prevedeva un array nel json, ma otteneva invece un oggetto.

Questa chiamata:

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

si aspetta una lista di Music oggetti, è per questo che funziona con il JSON:

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

Perché il JSON in sé è un array di tuoi Music oggetti (retrofit può convertire tra array json in liste java). Per il secondo, hai solo un oggetto e non un array (nota la mancanza di [...]). Per questo è necessario creare un'altra chiamata con un altro modello mappato a quel json. Supponiamo che tu abbia chiamato il modello MusicList. Ecco come la chiamata potrebbe apparire come:

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

(Si noti che potrebbe essere necessario cambiare il nome del metodo, se si vuole mantenere sia la prima chiamata e questo).

Il modello MusicList può essere simile a questa:

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

sto supponendo che l'array data è una lista di Music oggetti, ma ho notato che i jsons sono completamente differenti. Potrebbe essere necessario adattare anche questo, ma penso che si ottiene l'immagine qui.

+3

Grazie per i chiarimenti! – oxyt

+2

Grazie per questo –

+1

Grazie !!! :) –

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

Chiamare > getInbox(); –

Problemi correlati