@Override
public Response intercept(Chain chain) throws IOException
{
// First
Request request = chain.request();
Response response = chain.proceed(request);
....
....
....
// Retry empty body response requests for a maximum of 3 times
Integer retryMaxCount = 3;
MediaType contentType = response.body().contentType();
String bodyString = response.body().string();
while (bodyString.length() == 0 && retryMaxCount > 0)
{
//Empty body received!, Retrying...
retryMaxCount--;
response = chain.proceed(request);
bodyString = response.body().string();
}
if (bodyString.length() != 0)
{
// Create and return new response because it was consumed
ResponseBody newResponseBody = ResponseBody.create(contentType, bodyString);
return response.newBuilder().body(newResponseBody).build();
}
else
{
// WHAT TO WRITE HERE???
}
}
这篇文章帮助我实现了这个解决方案。感谢@mastov指明了正确的方向。
使用一个后端api,即使有错误也总是返回HTTP200。这是我对一个错误的响应示例
{"status":403,"message":"Bad User credentials","time":1495597740061,"version":"1.0"}
这里有一个简单的实现来补充这个答案。
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
ResponseBody body = response.body();
// Only intercept JSON type responses and ignore the rest.
if (body != null && body.contentType() != null && body.contentType().subtype() != null && body.contentType().subtype().toLowerCase().equals("json")) {
String errorMessage = "";
int errorCode = 200; // Assume default OK
try {
BufferedSource source = body.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
Charset charset = body.contentType().charset(Charset.forName("UTF-8"));
// Clone the existing buffer is they can only read once so we still want to pass the original one to the chain.
String json = buffer.clone().readString(charset);
JsonElement obj = new JsonParser().parse(json);
// Capture error code an message.
if (obj instanceof JsonObject && ((JsonObject) obj).has("status")) {
errorCode = ((JsonObject) obj).get("status").getAsInt();
}
if (obj instanceof JsonObject && ((JsonObject) obj).has("message")) {
errorMessage= ((JsonObject) obj).get("message").getAsString();
}
} catch (Exception e) {
Log.e(TAG, "Error: " + e.getMessage());
}
// Check if status has an error code then throw and exception so retrofit can trigger the onFailure callback method.
// Anything above 400 is treated as a server error.
if(errorCode > 399){
throw new Exception("Server error code: " + errorCode + " with error message: " + errorMessage);
}
}
return response;
}
我以为这些最新版本应该是兼容的。有一条推文;https://twitter.com/JakeWharton/status/553066921675857922和Retrofit 1.9的更新日志也提到了它。 然而,当我尝试这个: 还是不行。setClient方法抱怨不兼容的客户端对象; 我错过了什么?我还看到OkHttpClient没有实现客户端接口。 我现在使用这种方法;https://medi
D/OKHTTP:主机:www.appido.ir D/OKHTTP:Connection:Keep-Alive d/okhttp:accept-encoding:gzip 1048576------WebKitFormBoundaryJDHM3Si8Enjzaba内容-配置:表单-数据;name=“FlowCurrentChunkSize” 23016-----WebKitFormBoundar
我尝试使用OkHttp 3.12.0中最近添加的一个特性:全操作超时。为此,我还依赖retrofit 2.5.0中新的类,它允许我检索方法注释。 尽管它在使用拦截器中的链方法时工作得很好: 这是因为在呼叫排队之前必须设置呼叫超时吗?(而拦截器在过程中触发得太晚了?),或者这是其他原因?
我想拦截一个错误的JSON输入,并使用Dropwizard应用程序返回自定义错误消息。我遵循了这里提到的定义自定义异常映射器的方法:http://gary-rowe.com/agilestack/2012/10/23/how-to-implement-a-runtimeexceptionmapper-for-dropwizard/。但它不适合我。同样的问题也被问到这里https://groups.
当运行一个改型应用程序时,我得到以下错误: E/AndroidRuntime:致命异常:OkHttp Dispatcher进程:fr.univ_lehavre.greah.naoderapp,PID:20894java.lang.NosuchMethoderror:lokhttp3/internal/platform类中没有虚方法日志(ljava/lang/string;)V;或其超级类('OKH
1. 前言 拦截器这个名词定义的非常形象,就像导弹要攻击目标的时候,可能会被先进的反导系统拦截,此处的反导系统就是一种拦截器。 我们开发的应用,对外暴露的是控制器中定义的 API 方法,我们可以在 API 方法的外围放置拦截器,所有对 API 的访问都可以通过拦截器进行过滤。 OK,那么这样的拦截有什么意义吗,其实已经很明显了,反导系统可以保护目标的安全并识别对目标的攻击行为。同理,拦截器可以跟踪