如何通过 Retrofit 使用 Soundcloud API 中的分页 URL
How to work with pagination URL from Soundcloud API with Retrofit
我正在使用 Retrofit 从 Soundcloud 获取曲目列表-API。
请求导致带有曲目列表的回调 - 没有分页这有效。
但是当我将分页参数 (linked_partitioning=1) 添加到请求时,改造 returns 一个错误。我不知道如何编写回调类型来获取 URL-String 到下一页和我的列表结果。
改装电话:
Map<String, String> queryMap = new HashMap<String, String>();
queryMap.put("client_id" , My_Config.CLIENT_ID);
queryMap.put("tag", "loop" );
queryMap.put("license", "cc-by-sa" );
queryMap.put("limit", "10");
// This is causing a different Return Type ---> ERROR
queryMap.put("linked_partitioning", "1" );
scService = RetrofitRestAdapter.getService();
scService.searchTracks(queryMap, callback); // callback function success is not reached because of the ERROR
GET 请求的接口:
@GET("/tracks")
public void searchTracks(@QueryMap Map<String, String> filters, Callback<List<My_Track>> cb);
改造回调:
Callback<List<My_Track>> callbackTracks = new Callback<List<My_Track>>() {
@Override
public void success(List<My_Track> tracks, Response response) {...}
@Override
public void failure(RetrofitError error) {...}
};
改造异常:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
编辑:
Soundcloud 的结果模式 API:
没有分页结果是一个 Array/List 的 Track-Elements,看起来像这样:
[{"download_url":null,"key_signature":"","user_favorite":false,...},
{...},{...}]
分页结果是一个元素包含一个集合加上一个next_href:
{"collection":[
{"download_url":null,"key_signature":"",...},
{...},
{...}
],"next_href":"https://..."}
如何声明 Callback 的返回类型以将 Collection-Array 和 "next_href" 与 Result 分开?
谢谢!
根据您提供的错误,我可以猜测,在您请求分页后,API returns 生成的是对象而不是数组。例如,在使用分页之前,结果会像
[
{
item 1,
item 2
},
{
item 1,
item 2
}
]
使用分页后,结果会是这样
{
page: 1,
count: 400,
results: [
{
item 1,
item 2
},
{
item 1,
item 2
}
]
}
因此您可能需要更改分页映射。 (由于您没有提供结果模式,所以我认为这是您错误的原因)
编辑答案
目前您正在将返回的 JSON 映射到 My_Track class 的列表中。现在您需要创建另一个 class 用于映射,并将 My_Track 的列表声明为 属性。示例:
public class MyTrackHolder {
public final String next_href;
public final List<My_Track> collection;
public MyTrackHolder(final String next_href, final List<My_Track> collection)
{
this.next_href = next_href;
this.collection = collection;
}
}
你的界面会像
@GET("/tracks")
public void searchTracks(@QueryMap Map<String, String> filters, Callback<MyTrackHolder> cb);
最后调用这个接口方法如下
Callback<MyTrackHolder> callbackTracks = new Callback<MyTrackHolder>() {
@Override
public void success(MyTrackHolder trackHolder, Response response) {...}
@Override
public void failure(RetrofitError error) {...}
};
您可以使用
检索曲目
List<My_Track> tracks = trackHolder.collection;
我正在使用 Retrofit 从 Soundcloud 获取曲目列表-API。 请求导致带有曲目列表的回调 - 没有分页这有效。 但是当我将分页参数 (linked_partitioning=1) 添加到请求时,改造 returns 一个错误。我不知道如何编写回调类型来获取 URL-String 到下一页和我的列表结果。
改装电话:
Map<String, String> queryMap = new HashMap<String, String>();
queryMap.put("client_id" , My_Config.CLIENT_ID);
queryMap.put("tag", "loop" );
queryMap.put("license", "cc-by-sa" );
queryMap.put("limit", "10");
// This is causing a different Return Type ---> ERROR
queryMap.put("linked_partitioning", "1" );
scService = RetrofitRestAdapter.getService();
scService.searchTracks(queryMap, callback); // callback function success is not reached because of the ERROR
GET 请求的接口:
@GET("/tracks")
public void searchTracks(@QueryMap Map<String, String> filters, Callback<List<My_Track>> cb);
改造回调:
Callback<List<My_Track>> callbackTracks = new Callback<List<My_Track>>() {
@Override
public void success(List<My_Track> tracks, Response response) {...}
@Override
public void failure(RetrofitError error) {...}
};
改造异常:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
编辑: Soundcloud 的结果模式 API:
没有分页结果是一个 Array/List 的 Track-Elements,看起来像这样:
[{"download_url":null,"key_signature":"","user_favorite":false,...},
{...},{...}]
分页结果是一个元素包含一个集合加上一个next_href:
{"collection":[
{"download_url":null,"key_signature":"",...},
{...},
{...}
],"next_href":"https://..."}
如何声明 Callback 的返回类型以将 Collection-Array 和 "next_href" 与 Result 分开?
谢谢!
根据您提供的错误,我可以猜测,在您请求分页后,API returns 生成的是对象而不是数组。例如,在使用分页之前,结果会像
[
{
item 1,
item 2
},
{
item 1,
item 2
}
]
使用分页后,结果会是这样
{
page: 1,
count: 400,
results: [
{
item 1,
item 2
},
{
item 1,
item 2
}
]
}
因此您可能需要更改分页映射。 (由于您没有提供结果模式,所以我认为这是您错误的原因)
编辑答案
目前您正在将返回的 JSON 映射到 My_Track class 的列表中。现在您需要创建另一个 class 用于映射,并将 My_Track 的列表声明为 属性。示例:
public class MyTrackHolder {
public final String next_href;
public final List<My_Track> collection;
public MyTrackHolder(final String next_href, final List<My_Track> collection)
{
this.next_href = next_href;
this.collection = collection;
}
}
你的界面会像
@GET("/tracks")
public void searchTracks(@QueryMap Map<String, String> filters, Callback<MyTrackHolder> cb);
最后调用这个接口方法如下
Callback<MyTrackHolder> callbackTracks = new Callback<MyTrackHolder>() {
@Override
public void success(MyTrackHolder trackHolder, Response response) {...}
@Override
public void failure(RetrofitError error) {...}
};
您可以使用
检索曲目List<My_Track> tracks = trackHolder.collection;