如何使用moshi、Reformation和java处理包装数据?
我正在使用一个API,其中所有数据都包装在一个自定义对象中(见下文),因此我无法使用moshi将改装主体直接转换到我的模型。在这种情况下,与moshi合作的最佳方式是什么如何使用moshi、Reformation和java处理包装数据?,java,android,retrofit,moshi,Java,Android,Retrofit,Moshi,我正在使用一个API,其中所有数据都包装在一个自定义对象中(见下文),因此我无法使用moshi将改装主体直接转换到我的模型。在这种情况下,与moshi合作的最佳方式是什么 #COLLECTIONS ENDPOINT { "status": 200, "data": [ { "id": 28122, "name": "Aband
#COLLECTIONS ENDPOINT
{
"status": 200,
"data": [
{
"id": 28122,
"name": "Abandonei",
"counts": {
"books": 3
}
},
{
"id": 21091,
"name": "Lendo",
"counts": {
"books": 6
}
},
],
"errors": [],
"pagination": {
"after": 2,
"hasNextPage": true
}
}
所有api端点都使用相同的json结构,默认字段为:
{
"status": 200,
"data": [],
"errors": [],
"pagination": {
"after": 1,
"hasNextPage": true
}
}
我的收藏模式:
public class BookCollection {
public long id;
public String name;
public ArrayList<Book> books;
public BookCollection(long id, String name) {
this.id = id;
this.name = name;
}
}
公共类图书收藏{
公共长id;
公共字符串名称;
公共图书馆图书;
公共BookCollection(长id、字符串名称){
this.id=id;
this.name=名称;
}
}
您需要设置gson/moshi来使用您为json到对象映射创建的类。下面是这些java类的示例。您也可以在kotlin中使用数据类。对于moshi,您必须创建适配器来帮助实现json到对象的映射
publci class CollectionResponse {
public int status;
public List<BookCollection> data;
public List<Error> errors;
public Pagination pagination;
}
public class Pagination {
public int after;
public boolean hasNextPage;
}
public class BookCollection {
public long id;
public String name;
public Count counts;
}
public Count {
public int books;
}
public class Error {
}
publci类集合响应{
公众地位;
公开名单数据;
公开列表错误;
公共分页分页;
}
公共类分页{
公共int之后;
公共布尔值下一页;
}
公共类藏书{
公共长id;
公共字符串名称;
公众计数;
}
公众计数{
公共图书;
}
公共类错误{
}
您需要设置gson/moshi来使用您为json到对象映射创建的类。下面是这些java类的示例。您也可以在kotlin中使用数据类。对于moshi,您必须创建适配器来帮助实现json到对象的映射
publci class CollectionResponse {
public int status;
public List<BookCollection> data;
public List<Error> errors;
public Pagination pagination;
}
public class Pagination {
public int after;
public boolean hasNextPage;
}
public class BookCollection {
public long id;
public String name;
public Count counts;
}
public Count {
public int books;
}
public class Error {
}
publci类集合响应{
公众地位;
公开名单数据;
公开列表错误;
公共分页分页;
}
公共类分页{
公共int之后;
公共布尔值下一页;
}
公共类藏书{
公共长id;
公共字符串名称;
公众计数;
}
公众计数{
公共图书;
}
公共类错误{
}
为了避免为每个模型创建父类,我实现了一种使用接收泛型类型的类的方法
为了实现这一点,我将Moshi类更改为Gson
我的模型:
public class BookCollection {
public long id;
public String name;
public ArrayList<Book> books;
public BookCollection(long id, String name) {
this.id = id;
this.name = name;
}
}
用法:
public interface NetAPI {
@GET("me/collections")
Call<ResponseBody> getCollections(@Header("Authorization") String auth);
}
public class CollectionViewModel extends ViewModel {
private final MutableLiveData<List<Collection>> collections = new MutableLiveData<>();
private final MutableLiveData<Boolean> loading = new MutableLiveData<>();
private final MutableLiveData<Boolean> collectionError = new MutableLiveData<>();
private Call<ResponseBody> call;
private void fetchCollections() {
loading.setValue(true);
call = Api.getInstance().getCollections(TOKEN);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
collectionError.setValue(false);
//THE SECRET
Gson gson = new Gson();
ApiWrapper<List<Collection>> apiResponse = null;
apiResponse = gson.fromJson(response.body().string(), new TypeToken<ApiWrapper<List<Collection>>>(){}.getType());
collections.setValue(apiResponse.data);
loading.setValue(false);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(getClass().getSimpleName(), "Error loading data", t);
collectionError.setValue(true);
loading.setValue(false);
}
});
}
}
公共接口NetAPI{
@获取(“我/收藏”)
调用getCollections(@Header(“Authorization”)字符串auth);
}
公共类CollectionViewModel扩展了ViewModel{
private final MutableLiveData collections=新的MutableLiveData();
private final MutableLiveData loading=新的MutableLiveData();
私有最终MutableLiveData collectionError=新的MutableLiveData();
私人通话;
私有void fetchCollections(){
加载。设置值(真);
call=Api.getInstance().getCollections(令牌);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
试一试{
collectionError.setValue(假);
//秘密
Gson Gson=新的Gson();
apiResponse=null;
apiResponse=gson.fromJson(response.body().string(),newTypeToken(){}.getType());
collections.setValue(apiResponse.data);
加载设置值(false);
}捕获(IOE异常){
e、 printStackTrace();
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.e(getClass().getSimpleName(),“加载数据时出错”,t);
collectionError.setValue(真);
加载设置值(false);
}
});
}
}
通过这种方式,我可以将我的ApiWrapper类重用到任何模型(书籍、用户、登录等)
谢谢。为了避免为每个模型创建父类,我实现了一种使用接收泛型类型的类的方法 为了实现这一点,我将Moshi类更改为Gson 我的模型:
public class BookCollection {
public long id;
public String name;
public ArrayList<Book> books;
public BookCollection(long id, String name) {
this.id = id;
this.name = name;
}
}
用法:
public interface NetAPI {
@GET("me/collections")
Call<ResponseBody> getCollections(@Header("Authorization") String auth);
}
public class CollectionViewModel extends ViewModel {
private final MutableLiveData<List<Collection>> collections = new MutableLiveData<>();
private final MutableLiveData<Boolean> loading = new MutableLiveData<>();
private final MutableLiveData<Boolean> collectionError = new MutableLiveData<>();
private Call<ResponseBody> call;
private void fetchCollections() {
loading.setValue(true);
call = Api.getInstance().getCollections(TOKEN);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
collectionError.setValue(false);
//THE SECRET
Gson gson = new Gson();
ApiWrapper<List<Collection>> apiResponse = null;
apiResponse = gson.fromJson(response.body().string(), new TypeToken<ApiWrapper<List<Collection>>>(){}.getType());
collections.setValue(apiResponse.data);
loading.setValue(false);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(getClass().getSimpleName(), "Error loading data", t);
collectionError.setValue(true);
loading.setValue(false);
}
});
}
}
公共接口NetAPI{
@获取(“我/收藏”)
调用getCollections(@Header(“Authorization”)字符串auth);
}
公共类CollectionViewModel扩展了ViewModel{
private final MutableLiveData collections=新的MutableLiveData();
private final MutableLiveData loading=新的MutableLiveData();
私有最终MutableLiveData collectionError=新的MutableLiveData();
私人通话;
私有void fetchCollections(){
加载。设置值(真);
call=Api.getInstance().getCollections(令牌);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
试一试{
collectionError.setValue(假);
//秘密
Gson Gson=新的Gson();
apiResponse=null;
apiResponse=gson.fromJson(response.body().string(),newTypeToken(){}.getType());
collections.setValue(apiResponse.data);
加载设置值(false);
}捕获(IOE异常){
e、 printStackTrace();
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.e(getClass().getSimpleName(),“加载数据时出错”,t);
collectionError.setValue(真);
加载设置值(false);
}
});
}
}
通过这种方式,我可以将我的ApiWrapper类重用到任何模型(书籍、用户、登录等)
谢谢。您的型号现在有什么代码?您的moshi适配器应该能够处理此数据而不会出现任何问题。@RayHunter我添加了我在该请求中使用的模型,以及api在所有端点上返回的json示例。您的json需要与您的模型匹配。因此,与其说是布克科尔