使用Retrofit 1.6.0,OkHTTP 2.0.0和OkHTTP-UrlConnection 2.0.0.
我正在使用Retrofit对不存在的URL进行服务POST.正如预期的那样调用失败回调.但是,RetrofitError参数没有响应.我真的想抓住使用返回的HTTP状态代码
error.getResponse().getStatus()
Run Code Online (Sandbox Code Playgroud)
但由于getResponse()返回null,我不能.
为什么getResponse()为null,如何获取状态?
谢谢.
另外,我收到的错误是UnknownHostException,正如预期的那样.重复:我期待这个错误.我想知道如何获取HTTP状态代码或者为什么error.getResponse()返回null.
编辑:这是一些代码:
RestAdapterBuilderClass.java
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://badURL.DoesntMatter/");
.setRequestInterceptor(sRequestInterceptor)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
sService = restAdapter.create(ServiceInterface.class);
ServiceInterface.java
@POST("/Login")
void login(@Body JsonObject body, Callback<String> callback);
CallbackClass.java
@Override
public void failure(RetrofitError error) {
if (error.getResponse() == null) {
// error.getResponse() is null when I need to get the status code
// from it.
return;
}
}
Run Code Online (Sandbox Code Playgroud) 我希望使用OkHttp进行Retrofit,当没有Internet时使用缓存.
我准备OkHttpClient是这样的:
RestAdapter.Builder builder= new RestAdapter.Builder()
.setRequestInterceptor(new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json;versions=1");
if (MyApplicationUtils.isNetworkAvaliable(context)) {
int maxAge = 60; // read from cache for 1 minute
request.addHeader("Cache-Control", "public, max-age=" + maxAge);
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
request.addHeader("Cache-Control",
"public, only-if-cached, max-stale=" + maxStale);
}
}
});
Run Code Online (Sandbox Code Playgroud)
并像这样设置缓存:
Cache cache = null;
try {
cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
} catch …Run Code Online (Sandbox Code Playgroud) 我正在努力让一些罐头网络响应.我对实际请求有json响应,并且我有Retrofit接口来序列化响应.试图设置它我感到非常沮丧.我该怎么办?看来我的选择是,1)使用MockWebServer()2)使用RequestInterceptor().
在尝试使用1或2时,我不能在我的生活中实例化OkHttpClient()而不会失败,基本上这会把我试图立即死亡的每一件事.我得到一个java.lang.AssertionError,因为当OkHttpClient无法找到TLS算法时会抛出它.
if (builder.sslSocketFactory != null || !isTLS) {
this.sslSocketFactory = builder.sslSocketFactory;
} else {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
this.sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
**throw new AssertionError(); // The system has no TLS. Just give up.**
}
}
Run Code Online (Sandbox Code Playgroud)
我试图使用unMock在android.jar中保留"javax.net.ssl"类,但这并没有解决错误.
unMock {
// URI to download the android-all.jar from. e.g. https://oss.sonatype.org/content/groups/public/org/robolectric/android-all/
downloadFrom 'https://oss.sonatype.org/content/groups/public/org/robolectric/android-all/4.3_r2-robolectric-0/android-all-4.3_r2-robolectric-0.jar'
keep "android.util.Log"
keep "javax.net.ssl"
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,我已经遇到过如何通过改造2模拟网络请求的各种示例,但我无法克服这个障碍,而且我感觉很失败.我还没有看到其他人遇到过这个问题,而且我很困惑于每个人如何在所有测试中轻松实例化新的OkHttpClients.
以下是我正在使用的相关依赖项.
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-all:1.10.19'
testCompile 'org.powermock:powermock-mockito-release-full:1.6.4'
testCompile 'org.powermock:powermock-module-junit4:1.6.4'
testCompile 'org.easymock:easymock:3.4'
testCompile 'org.powermock:powermock-api-easymock:1.6.4'
testCompile …Run Code Online (Sandbox Code Playgroud) 我正在使用改造2和OkHttp3从服务器请求数据.我刚刚添加了一个离线缓存代码,但它没有按预期工作.我收到错误"无法解析主机"<>":没有与主机名关联的地址."
当它试图从缓存中获取检索数据时(没有互联网连接时)会发生这种情况.下面是一段代码片段.
public static Interceptor provideCacheInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// re-write response header to force use of cache
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.build();
}
};
}
public static Interceptor provideOfflineCacheInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!hasNetwork) {
CacheControl cacheControl = new CacheControl.Builder()
.onlyIfCached()
.maxStale(7, TimeUnit.DAYS) …Run Code Online (Sandbox Code Playgroud) 我有一个数据驱动的Android应用程序支架.添加测试,旨在实现100%的覆盖率.使用OkHttp.
如何使用模拟响应透明地拦截对我的服务器的调用?
想要这种端到端和单元测试.例如:设置build-type MockServer应该加载一个将在模拟器中显示模拟响应的应用程序.
有没有办法检测Retrofit响应是来自配置的OkHttp缓存还是实时响应?
客户定义:
Cache cache = new Cache(getCacheDirectory(context), 1024 * 1024 * 10);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cache(cache)
.build();
Run Code Online (Sandbox Code Playgroud)
Api定义:
@GET("/object")
Observable<Result<SomeObject>> getSomeObject();
Run Code Online (Sandbox Code Playgroud)
示例电话:
RetroApi retroApi = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(RetroApi.class);
result = retroApi.getSomeObject().subscribe((Result<SomeObject> someObjectResult) -> {
isFromCache(someObjectResult); // ???
});
Run Code Online (Sandbox Code Playgroud) 在我的Android应用程序中,我正在尝试切换android-async-http到okhttp支持异步网络sind版本2.0的.虽然前者发布了持久性cookie存储的实现,但我不知道如何实现这样的东西okhttp.
在我的应用程序中,我有一个登录例程,在此期间get发送请求,如果成功,则应设置cookie.此cookie应附加到所有后续网络请求,并应在应用程序重新启动后继续存在.
我在SO上找到了以下答案,表明如果在应用程序的某个地方执行以下代码,则会激活持久性cookie管理并okhttp使用它:
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);
Run Code Online (Sandbox Code Playgroud)
但是,对我来说它不起作用.是CookieManager正确的方法吗?我如何监控设置和存储哪些cookie以进一步调试问题?
我正在使用带有okhttp 2.4.0的Retrofit 1.9.到目前为止,我们在服务器端禁用了SPDY协议(我通过此检查).服务器端的启用协议是HTTP/2(我通过此检查).
所以我认为okhttp将尝试使用HTTP/2(最新的一个协议)进行api调用,但它在Android设备4.2.2 samsung S4上使用HTTP/1.1 -
D/Retrofit : OkHttp-Selected-Protocol: http/1.1
Run Code Online (Sandbox Code Playgroud)
有人告诉我Android设备直到5.0 才支持SPDY(我没有任何证据),因此该设备从未尝试过使用SPDY连接.但我确信我们的服务器根本没有使用SPDY我自己使用上面的链接检查了它.
并且okhttp开始支持HTTP/2,因为它是2.3.0版本,请参见此处.
如果我在上面的Android 5.0中使用相同的东西,我在生产应用程序上获得了相同配置(okhttp 2.4.0和Retrofit 1.9)的异常 -
java.net.ProtocolException: Expected ':status' header not present at
com.squareup.okhttp.internal.http.SpdyTransport.readNameValueBlock(SpdyTransport.java:197)at com.squareup.okhttp.internal.http.SpdyTransport.readResponseHeaders(SpdyTransport.java:104)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917)
at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:95)
at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:902)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:760)
at com.squareup.okhttp.Call.getResponse(Call.java:274)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
at com.squareup.okhttp.Call.execute(Call.java:81)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
Run Code Online (Sandbox Code Playgroud)
有两个修复 -
强制okhttp只使用http/1.1 -
OkHttpClient客户端=新的OkHttpClient(); client.setProtocols(Arrays.asList(Protocol.HTTP_1_1));
注意 - 我们不能使用Protocol.HTTP_2或Protocol.SPDY_3,因为如果 …
我有下面的方法,它执行 GET 请求 3 次,直到它成功。
模拟这种方法的更好方法是什么?我想模拟和测试 status_code 401、状态码 500 并想测试该方法是否执行三次。
在 python 中,我们有https://github.com/getsentry/responses直接模拟请求,所以很容易测试这些方法。
Java中是否有任何等效的东西。
@Override
public <T> UResponse<T> get(Request request, JSONUnmarshaler<T> unmarshaller, Gson gson) throws UException {
int status_code = 0;
String next = null;
String rawJSON = null;
JsonElement jsonelement = null;
Boolean retry = true;
try {
int attempts = 3;
while ((attempts >= 0) && (retry) && status_code != 200){
Response response = this.client.newCall(request).execute();
rawJSON = response.body().string();
jsonelement = gson.fromJson(rawJSON, JsonElement.class);
next = gson.fromJson(jsonelement.getAsJsonObject().get("next"), String.class); …Run Code Online (Sandbox Code Playgroud) 我无法运行任何测试或运行应用程序或调试器,因为this error:
`Unable to find method void org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions.setUseIR(boolean)`
Run Code Online (Sandbox Code Playgroud)
我已经尝试了所有提供的解决方案并点击了该File > Invalidate Caches/Restart...选项。
这是一个使用 Kotlin 和 Java 编写的 Android Studio 项目,包含 Jetpack Compose、Retrofit2、OkHttp3。
更新:这是我的 build.gradle 文件
buildscript {
ext.kotlin_version = '1.6.0-RC'
ext {
compose_version = '1.0.1'
fragment_version = "1.3.6"
}
repositories {
google()
mavenCentral()
maven {
url = uri("https://plugins.gradle.org/m2/")
}
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle …Run Code Online (Sandbox Code Playgroud)