我正在测试一个支持HTTP/2的站点,就像这样,我尝试使用okhttp发送请求:
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.google.it")
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Response response) throws IOException {
Log.d("TestHttp", "OkHttp-Selected-Protocol: " + response.header("OkHttp-Selected-Protocol"));
Log.d("TestHttp", "Response code is " + response.code());
}
});
Run Code Online (Sandbox Code Playgroud)
在日志中我得到了这样的东西:
OkHttp-Selected-Protocol: http/1.1
Run Code Online (Sandbox Code Playgroud)
okhttpClient选择使用http/1.1,如何强制它使用HTTP/2?
我有一个使用OkHttp的Android SDK.在我使用我的SDK的示例应用程序中,一切正常.然而,我的一个用户,当StrictMode打开时,得到以下内容java.lang.Throwable: Explicit termination method 'close' not called.我已经尝试在我自己的应用程序中使用StrictMode复制它,并且不会出现此错误.
我知道我应该打电话,response.body().close()但我仍然有点困惑为什么在我的应用程序中没有发生这种情况.他发给我的堆栈跟踪只有我的类,所以看起来他的代码中没有任何东西导致它.
另外值得注意的是,我的SDK中只有一个请求实际上有响应读取.但这不是我的用户所说的导致异常的请求.
还有什么可能导致这个吗?
我该.close()什么时候打电话?打电话后立即打电话execute()是可取的吗?关闭身体是否会阻止将来阅读?
我正在使用Retrofit 2.0b2.得到回复后,我尝试通过以下方式从响应中获取InputStream:
Response<JsonNode> response = call.execute();
InputStream is = response.raw().body().byteStream();
Run Code Online (Sandbox Code Playgroud)
但应用程序继续投掷:
java.lang.IllegalStateException: Cannot read raw response body of a converted body.
at retrofit.OkHttpCall$NoContentResponseBody.source(OkHttpCall.java:184)
at com.squareup.okhttp.ResponseBody.byteStream(ResponseBody.java:43)
at ...
Run Code Online (Sandbox Code Playgroud)
尽管响应正确返回.我在这做错了什么?
我有一些具有相同baseUrl的服务URL.对于某些网址,会有一些常用的参数,例如apiVersion或locale.但它们不必存在于每个URL中,因此我无法将它们添加到baseUrl中.
.../api/{apiVersion}/{locale}/event/{eventId}
.../api/{apiVersion}/{locale}/venues
.../api/{apiVersion}/configuration
Run Code Online (Sandbox Code Playgroud)
我不想在改装界面中添加这些参数.在改造1中,我制作了一个拦截器并用于RequestFacade.addPathParam(..., ...)填充每个URL的这些常用路径参数.
对于改造2,我似乎找不到用okhttp做这个的正确方法.我现在看到这种可能性的唯一方法是HttpUrl从Chain.request().httpUrl();一个okhttp中获取Interceptor并自己操纵那个,但我不知道这是否是最好的方法.
有没有人遇到过更好的方法来替换okhttp中的路径参数Interceptor?
在撰写本文时,我正在使用改进:2.0.0-beta2和okhttp:2.7.2.
在执行enque操作之前,我需要获取请求主体并使用Retrofit 2.0执行一些逻辑操作.但遗憾的是,我无法通过服务电话获取帖子正文内容.目前搜索了很多之后,我发现好像只有一个办法logging了request,我现在用的改造2.0可以发布该方法通过使用HttpLoggingInterceptor具有OkHttpClient.我使用以下代码在Android Logcat中记录请求正文:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BODY);
OkHttpClient httpClient = new OkHttpClient();
httpClient.interceptors().add(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(apiClass);
Run Code Online (Sandbox Code Playgroud)
问题我面对上述方法:
02-04 01:35:59.235 5007-5035/com.example.retrofitdemo D/OkHttp:{"nameValuePairs":{"id":"1","name":"chandru","type":"user"}}
但是上面的方法只返回logcat中的响应体,我无法将其作为String或者JSONObject.尽管如果我能够使用响应体HttpLoggingInterceptor,我的请求体将一直显示在Logcat中,标签为"OkHttp",即使在应用程序进入生产之后也是如此(所以主要是这样一种解除帖子的方式logcat中的数据).
我的要求:
我需要在不对Logcat中的post数据进行修改的情况下将请求体作为String或者JSONObject任何方法获取.
我尝试了什么:
我试图获取请求正文,即使onResponse从以后Response<T> response,但我无法完成它可能.请找到我为此目的使用的代码,如下所示:
Gson gson = new Gson();
String responseString = gson.toJson(response.raw().request().body());
Run Code Online (Sandbox Code Playgroud)
注意:上述转换后的请求正文使用gson.toJson方法仅返回元数据而非请求发布数据.
请提供宝贵的提示和解决方案,帮助我解决这个问题.我不知道该怎么做.过去两天我完全坚持了这一点.如果我的问题太冗长,请原谅.欢迎你提出任何建议.如果我的要求不明确,请告诉我.提前致谢.
当我使用这样的异步方式使用OkHttp库时:
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
Run Code Online (Sandbox Code Playgroud)
在onFailure方法中,我如何获得响应状态代码以区分不同的错误.例如,网络错误或服务器错误?
我正在为OkHttpClient设置重试连接失败选项.
client = new OkHttpClient();
client.setRetryOnConnectionFailure(true);
Run Code Online (Sandbox Code Playgroud)
我想知道它会继续尝试多少次.查看源代码,我没有看到任何最大限制.如何配置客户端在几次尝试后停止尝试?
我正在尝试清除日志中的垃圾,例如
*?$?x???J/
当我收到图像时
因此,我尝试覆盖 HttpLoggingInterceptor 拦截(),以检测响应中是否存在 Content-Type => image/jpeg 标头,但 HttpLoggingInterceptor 是最终的,因此我无法扩展它:(
RetrofitModule 中的代码:
OkHttpClient provideOkHttpClient(Context context, Application app, Preferences preferences) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.HEADERS);
Cache cache = new Cache(app.getCacheDir(), cacheSize);
return new OkHttpClient.Builder()
.addNetworkInterceptor(new OkHttpInterceptor(context, preferences))
.addInterceptor(loggingInterceptor)
.cache(cache)
.build();
}
Run Code Online (Sandbox Code Playgroud)
如何在我的项目中禁用图像记录?
我没有找到任何有关如何替换弃用方法的示例。okhttp3主页上的示例很旧。这是其中之一:
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
Run Code Online (Sandbox Code Playgroud)
如果有人可以解决,请多多帮助。
更新:我正在使用'com.squareup.okhttp3:okhttp:4.0.1'
有没有办法获取请求的最终URL?我知道我可以自己禁用重定向,但有没有办法获取我正在加载的当前URL?就像,如果我要求a.com并被重定向到b.com,有没有办法获得url b.com的名称?