使用 JSend 格式通过 Retrofit 将 JSON 响应转换为 POJO?
Posted
技术标签:
【中文标题】使用 JSend 格式通过 Retrofit 将 JSON 响应转换为 POJO?【英文标题】:Converting JSON response to POJO with Retrofit using JSend format? 【发布时间】:2017-07-20 12:48:38 【问题描述】:我必须使用使用 JSend 格式的 API。
长话短说,它使用的是 HTTP 状态代码,表示状态如下:
200 就是成功 406 未经授权这很好,因为我可以从中确定我的 API 请求是否成功。
但是:
由于 JSend 格式有它自己的东西,它在响应时也有一个小的状态指示器,就像这样:
status : "success",
data : "post" : "id" : 2, "title" : "Another blog post", "body" : "More content"
所以它有一个“状态”字段,它还显示 API 请求是否成功。
问题:
为了解析对 POJO 的响应而进行了改造,因此它假定响应仅包含模型并且没有成功的指示符,例如:(模型后实例)
"id" : 2, "title" : "Another blog post", "body" : "More content"
我的问题是:
有解决办法吗? 我可以预先解析状态指示符,拆分响应的“数据”(模型)部分,然后再对其进行改造以仅解析该部分吗?
如果不是,我将不得不为我的每个模型添加一个“状态”属性,这显然不是一种可步行的方式,我不会这样做。
我是否应该坚持手动解析并使用ResponseBody
而不是我的模型在
void onResponse(Call<T> call, Response<T> response);
为T
类型参数?
因为这样我可以使用.string()
并将字符串转换为 JSON,然后我可以手动解析我的模型,就像为它们编写解析器一样。
我真的很想使用 Retrofit 的功能进行自动解析,因为有了JSend,我无法想象如果无论如何要做到这一点。
我无法更改 API,它将成为这种方式。
【问题讨论】:
【参考方案1】:你可以做的是你可以在不使用它的情况下获得发布请求的状态。 问题是参数名称不是字符串,在POJO中不会被解析。但是你可以像这样得到你请求的状态。
@Override
public void onResponse(Call<Object> call, retrofit2.Response<Object> response)
alertDialog.dismiss();
if (response.isSuccessful() && response.body() != null)
//if the response is received here it means it was success
else if(response.errorBody()!=null)
//if the response is received here it means it was error
@Override
public void onFailure(Call<Object> call, Throwable t)
//if the response is received here it means it was failure
t.printStackTrace();
);
编辑 通过这种方式,您可以获得使用 pojo 的状态,并且您可以像 link 中那样简单地解析错误
编辑 1 此外,为了获得正确的错误代码,您可以将回调类扩展为类似
public class ErrorValues
public int code=0;
public String error;
然后如果请求完成有错误。里面
else if(response.errorBody()!=null)
int error=response.body.code == 404 ....
这样你可以检查请求抛出了哪个错误代码。
【讨论】:
【参考方案2】:一种可能的方法是为您的模型创建一个包装器,例如
public class Example<T>
String status;
T data;
public String getStatus()
return status;
public void setStatus(String status)
this.status = status;
public T getData()
return data;
public void setData(T data)
this.data = data;
【讨论】:
【参考方案3】:这是我的Response
课程。
public class Response<T> implements Serializable
private T data;
private String status;
public T getData()
return data;
public void setData(T data)
this.data = data;
public String getStatus()
return status;
public void setStatus(String status)
this.status = status;
这是我的 api 调用。
Callback<com.shippn.api.models.Response<T>> callback = new Callback<com.shippn.api.models.Response<T>>()
@Override
public void onResponse(Call<com.shippn.api.models.Response<T>> call, Response<com.shippn.api.models.Response<T>> response)
checkStatus(response.body());
@Override
public void onFailure(Call<com.shippn.api.models.Response<T>> call, Throwable t)
fail();
;
call.enqueue(callback);
T
参数是来自 api 的数据类型。我的意思是,如果你想在Post
中获取数据,请输入Post
insted of T
。如果你想得到ArrayList<Post>
,请输入ArrayList<Post>
。
如果您的 api 响应中data
字段为空或 null,Response.data
将为 null 或空,它不会抛出异常。
当您收到 api 的响应时,首先检查 Response.status
是否“成功”。如果是“成功”,则从Response
获取数据,如果不是,则采取您的错误操作。
【讨论】:
优雅的解决方案。谢谢。 我很高兴听到这个消息,也感谢@AdamVarhegyi 的赏金以上是关于使用 JSend 格式通过 Retrofit 将 JSON 响应转换为 POJO?的主要内容,如果未能解决你的问题,请参考以下文章
使用Retrofit2+RxJava2+ProtoBuf实现网络请求
如何使用Retrofit解决IllegalArgumentException“格式错误的内容类型:...”
使用 Retrofit 上传 JSON 格式的多部分图像数据?
当列表的各个项目使用Retrofit和Gson的格式不同时,如何解析json列表?