Reputation: 78
I'm trying to consume a service by using retrofit 2. When I call it using a web browser or log the call using an interceptor, there're some results, but my pojo classes are always empty.
The json result content is similar to:
{
"similarartists": {
"artist": [
{
"name": "Barão Vermelho",
"mbid": "84ac395b-482b-48cb-b381-b9bc420b2dd3",
"match": "1",
"url": "https://www.last.fm/music/Bar%C3%A3o+Vermelho",
"image": [],
"streamable": "0"
},
"@attr": {
"artist": "Cazuza"
}
}
}
And these are my pojo classes:
public class Similarartists {
@SerializedName("artist")
private List<Artist> artist = new ArrayList<>();
@SerializedName("attr")
private Attr attr;
}
public class Artist {
@SerializedName("name")
private String name;
@SerializedName("mbid")
private String mbid;
@SerializedName("match")
private String match;
@SerializedName("url")
private String url;
@SerializedName("image")
private List<Object> image = new ArrayList<>();
@SerializedName("streamable")
private String streamable;
}
public class Attr {
@SerializedName("artist")
private String artist;
}
The service connection class:
public class ApiService {
private static final String BASE_URL = "http://ws.audioscrobbler.com/";
public static final String API_KEY = "XXXXXXXXXX";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.connectTimeout(30, TimeUnit.SECONDS);
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}
Ans this is my "button" action:
private void openSearchDialog() {
ArtistService artistService = ApiService.createService(ArtistService.class);
Call<Similarartists> call = artistService.getSimilar("nirvana", ApiService.API_KEY);
call.enqueue(new Callback<Similarartists>() {
@Override
public void onResponse(Call<Similarartists> call, Response<Similarartists> response) {
if (response.isSuccessful()) {
mAdapter.setValues(response.body().getArtist());
Log.i(TAG, "onResponse: " + response.body().toString());
}
}
@Override
public void onFailure(Call<Similarartists> call, Throwable t) {
Log.e(TAG, "onFailure: ", t);
}
});
}
The problem is response.body().getArtist() is always empty. Please help me.
And this's my log result:
-01 22:51:58.844 23843-24043/com.sample.pablo.hellomusic D/OkHttp: {"similarartists":{"artist":[{"name":"Hole","mbid":"1dcc8968-f2cd-441c-beda-6270f70f2863","match":"1","url":"https://www.last.fm/music/Hole","image":[{"#text":"https://lastfm-img2.akamaized.net/i/u/34s/6687f63408074388ae703eb3905e238f.png","size":"small"},{"#text":"https://lastfm-img2.akamaized.net/i/u/64s/6687f63408074388ae703eb3905e238f.png","size":"medium"},{"#text":"https://lastfm-img2.akamaized.net/i/u/174s/6687f63408074388ae703eb3905e238f.png","size":"large"},{"#text":"https://lastfm-img2.akamaized.net/i/u/300x300/6687f63408074388ae703eb3905e238f.png","size":"extralarge"},{"#text":"https://lastfm-img2.akamaized.net/i/u/6687f63408074388ae703eb3905e238f.png","size":"mega"},{"#text":"https://lastfm-img2.akamaized.net/i/u/arQ/6687f63408074388ae703eb3905e238f.png","size":""}],"streamable":"0"}],"@attr":{"artist":"Nirvana"}}}
Upvotes: 0
Views: 541
Reputation: 32748
Since there is a top-level key of similarartists
in the response JSON I think you need another wrapper around this object, like:
public class SimilarArtistsResponse {
@SerializedName("similarartists")
private Similarartists similars;
}
And its this object you would specify in your Call<SimilarArtistsResponse>
Upvotes: 1