改造回调获取响应体
Posted
技术标签:
【中文标题】改造回调获取响应体【英文标题】:Retrofit callback get response body 【发布时间】:2014-04-15 01:26:17 【问题描述】:我正在测试 Retrofit 以将其与 Volley 进行比较,我正在努力从我的请求中获得响应。例如,我做这样的事情:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://localhost:8080")
.build();
MyService service = restAdapter.create(MyService.class);
service.getToto("toto", new Callback<Toto>()
@Override
public void success(Toto toto, Response response)
// Try to get response body
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try
reader = new BufferedReader(
new InputStreamReader(response.getBody().in()));
String line;
try
while ((line = reader.readLine()) != null)
sb.append(line);
catch (IOException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
String result = sb.toString();
@Override
public void failure(RetrofitError error)
);
有效,对象toto
已设置,但出于测试目的,我还想显示服务器返回的JSON响应。
所以我试图从response.getBody()
读取InputStream
,这是一个TypedInputStream
。
不幸的是,我总是收到IOException : Stream is closed
。
我尝试使用 Retrofit 中的 Utils 类,但得到相同的 IOException
错误。
【问题讨论】:
我认为您可以使用自定义转换器将解析委托给真正的转换器并记录服务器的响应More info here 我也有同样的问题。同样简单的设置,我的实际自定义响应对象很好,填充了等等,但是当我尝试直接从响应中获取输入流时,同样的错误。但failure()
中的响应输入流工作正常
实际上只是注意到了一些奇怪的事情。当我打开登录改造时,它会吐出我想看到的所有信息,我的输入流消耗工作正常,没有抛出错误。奇怪...
@trippedout 请看下面我的回答...
您可以使用JsonObject
作为响应,然后从josnObject.toString()
获取您的String
【参考方案1】:
在回调的尖括号中写入“Response”,然后从该响应中提取流。
service.getToto("toto", new Callback<Response>()
@Override
public void success(Response result, Response response)
//Try to get response body
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
String line;
try
while ((line = reader.readLine()) != null)
sb.append(line);
catch (IOException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
String result = sb.toString();
@Override
public void failure(RetrofitError error)
);
【讨论】:
@Kerwan 如果这个答案对你有帮助,请选择这个答案并投票,这样它也可以帮助其他人 好的,谢谢!我忘了我的问题,我改用 Volley,但你的解决方案有效:) 如果我按照你的方法,我得到一个错误:retrofit.RetrofitError: No Retrofit annotation found。 (参数#2) @IgorGanapolsky 试试我的其他答案。可能会帮助你。链接***.com/questions/23853552/… @NiteshKhatri 我的主要问题是在 RXJava observable 中指定数据类型和回调。就 RXJava 而言,Retrofit 仅返回一个回调(可观察)。所以我现在只是将 Retrofit Response 作为唯一的返回类型进行内省,问题就消失了。【参考方案2】:改造 2.0 之前
String bodyString = new String(((TypedByteArray) response.getBody()).getBytes());
改造 2.0
String bodyString = new String(response.body().bytes());
【讨论】:
这个解决方案很棒,因为我可以有我的响应类型并吃掉它。 @shiami 无法解析符号“TypedByteArray”。我在哪里可以上这门课? @anivaler 我认为它不再适用于 Retrofit 2.0+ bodyString = new String(response.body().bytes());改造 2.0 @Robert 我在尝试这行代码时收到“无法解析方法 'bytes()'”。【参考方案3】:如果您在用于创建服务的RestAdapter
上设置.setLogLevel(RestAdapter.LogLevel.FULL)
,您应该在调试控制台中获得原始 JSON 响应输出。
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("http://my_lovely_api.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
mService = restAdapter.create(MyService.class);
如果你想对这个原始响应做一些不同的事情,你仍然可以使用你在成功块中的代码来创建一个 JSON 字符串,假设你在 setLogLevel
方法中保留 LogLevel.FULL
,如果没有,那么它不会解析来自 response.getBody().in()
的 InputStream,因为它已被读取并关闭。
【讨论】:
太棒了! .setLogLevel(RestAdapter.LogLevel.FULL) 帮助我 这仅在您的应用程序在 DEBUG 中运行时有用。这是一个很好的解决方案,特别是因为我们不想登录发布版本。不幸的是,我不得不在发布版本中编写日志。因此,此解决方案在这种情况下不起作用。我正在使用改造 1.9【参考方案4】:我最近遇到了类似的问题。我想查看响应正文中的一些 json,但不想处理 Retrofit 中的 TypedByteArray。我发现解决它的最快方法是制作一个带有单个字符串字段的 Pojo(普通旧 Java 对象)。更一般地,您会制作一个 Pojo,其中一个字段对应于您想要查看的任何数据。
例如,假设我正在发出一个请求,其中来自服务器的响应是响应正文中名为“access_token”的单个字符串
我的 Pojo 应该是这样的:
public class AccessToken
String accessToken;
public AccessToken()
public String getAccessToken()
return accessToken;
然后我的回调看起来像这样
Callback<AccessToken> callback = new Callback<AccessToken>()
@Override
public void success(AccessToken accessToken, Response response)
Log.d(TAG,"access token: "+ accessToken.getAccessToken());
@Override
public void failure(RetrofitError error)
Log.E(TAG,"error: "+ error.toString());
;
这将使您能够查看您在回复中收到的内容。
【讨论】:
【参考方案5】:请不要为此使用流和 straemReaders。 使用像 square 这样的智能解决方案:
private Response logAndReplaceResponse(String url, Response response, long elapsedTime)
http://www.programcreek.com/java-api-examples/index.php?source_dir=retrofit-jaxrs-master/retrofit/src/main/java/retrofit/RestAdapter.java
示例:
private String getResponseBody(Response response)
String result = "";
//Try to get response body
if (response.getBody() instanceof TypedByteArray)
TypedByteArray b = (TypedByteArray) response.getBody();
result = new String(b.getBytes());
return result;
【讨论】:
【参考方案6】:另一种解决方案是执行以下操作:
private static String bodyAsString(RequestBody body)
try
Buffer buffer = new Buffer();
body.writeTo(buffer);
return buffer.readString(body.contentType().charset());
catch (IOException e)
throw new RuntimeException(e);
取自https://github.com/square/okhttp/blob/master/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java#L93-L101
【讨论】:
【参考方案7】:使用 2.1.0 版本,您可以获取内容为
public void onResponse(Call<T> call, Response<T> response)
String errorString = response.errorBody().string();
【讨论】:
【参考方案8】:就这样吧:
ModelClass modelclass=response.response.body()
System.out.println("****************-----retro rsp----1-------"+modelclass.getMessage());
【讨论】:
【参考方案9】:在您的响应模型中按 cmd+n 并覆盖“toString”方法,并且仅调用 response.toString();
@Override
public String toString()
return "" +
"key_one='" + var_keyone + '\'' +
", key_two='" + var_keytwo + '\'' +
'';
【讨论】:
以上是关于改造回调获取响应体的主要内容,如果未能解决你的问题,请参考以下文章