我正在使用Google Volley和Gson编写我的应用程序,使用OkHttp作为HTTP-Stack与REST服务进行通信.这大部分时间都很好用但是当我暂停我的应用并返回它时,HTTP请求不能用于此异常:
09-08 19:29:19.611: E/ASDF(21827): com.android.volley.NoConnectionError: java.io.EOFException
09-08 19:29:19.611: E/ASDF(21827): at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:125)
09-08 19:29:19.611: E/ASDF(21827): at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)
09-08 19:29:19.611: E/ASDF(21827): Caused by: java.io.EOFException
09-08 19:29:19.611: E/ASDF(21827): at java.util.zip.GZIPInputStream.readFully(GZIPInputStream.java:206)
09-08 19:29:19.611: E/ASDF(21827): at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:98)
09-08 19:29:19.611: E/ASDF(21827): at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:81)
09-08 19:29:19.611: E/ASDF(21827): at com.squareup.okhttp.internal.http.HttpEngine.initContentStream(HttpEngine.java:461)
09-08 19:29:19.611: E/ASDF(21827): at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:659)
09-08 19:29:19.611: E/ASDF(21827): at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:346)
09-08 19:29:19.611: E/ASDF(21827): at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:295)
09-08 19:29:19.611: E/ASDF(21827): at com.squareup.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:489)
09-08 19:29:19.611: E/ASDF(21827): at com.squareup.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:136)
09-08 19:29:19.611: E/ASDF(21827): at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:109)
09-08 19:29:19.611: E/ASDF(21827): at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)
09-08 19:29:19.611: …Run Code Online (Sandbox Code Playgroud) 我正在使用Auth0,它给了我一个JWT(json web令牌)和一个refreshtoken.我在http标头中使用此JWT与我的后端进行通信.
403当它确定JWT已经过期时,它可能会发生,服务器给我一个.在这种情况下,我可以让Auth0使用refreshtoken向我发出一个新的JWT.这意味着我调用Auth0后端,将它传递给refreshtoken,它给了我一个新的JWT,然后我可以在我的请求中使用它.
我的问题是,如何在我的所有网络代码中有效地编写此行为?我将有几个端点可以交谈,他们都可以返回403.
我想我应该首先制作一个拦截器,将JWT添加到所有请求中.
然后应该有检测403的行为,静静地对Auth0进行网络调用,检索新的JWT.然后应该再次尝试原始请求,并在其标题中添加新的JWT.
所以我更希望将403处理到我的其他代码看不到的地方,并且绝对不必在任何地方重写它.
任何关于如何实现这一点的指示将不胜感激.
-
要清楚,我基本上是在寻找如何使用RxAndroid Observables实现这一目标的指针.当某个Observable找到403时,它应该"注入"一个新的网络呼叫.
我有一个.p12证书文件,我使用SSL转换器将其转换为.pem证书文件.然后我在我的android代码中使用那个pem证书文件,如下所示:
OkHttpClient okHttpClient = new OkHttpClient();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream instream = context.getResources().openRawResource(R.raw.pem_certificate);
Certificate ca;
ca = cf.generateCertificate(instream);
KeyStore kStore = KeyStore.getInstance(KeyStore.getDefaultType());
kStore.load(null, null);
kStore.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(kStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
} catch (CertificateException
| KeyStoreException
| NoSuchAlgorithmException
| IOException
| KeyManagementException e) {
e.printStackTrace();
}
baseURL = endpoint;
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(baseURL)
.setClient(new OkClient(okHttpClient))
.build();
service = restAdapter.create(DishService.class);
Run Code Online (Sandbox Code Playgroud)
但是这段代码不起作用.它在"ca = cf.generateCertificate(instream);"行中失败了.使用CertificateException消息.
我正在尝试使用Retrofit 1.9.0和配置缓存OkHtttp 2.5.0.
以下是我为我提供OkHttpClient的方式RestAdapter:
@Provides
@Singleton
public OkHttpClient provideOkHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
File cacheDir = new File(context.getCacheDir(), "http");
final Cache cache = new Cache(cacheDir, DISK_CACHE_SIZE_IN_BYTES);
okHttpClient.setCache(cache);
okHttpClient.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(request);
Response finalResponse = response.newBuilder()
.header("Cache-Control", String.format("public, max-stale=%d", 604800))
.build();
Log.d("OkHttp", finalResponse.toString());
Log.d("OkHttp Headers", finalResponse.headers().toString());
return finalResponse;
}
});
return okHttpClient;
}
Run Code Online (Sandbox Code Playgroud)
我没有忘记 …
我收到了这个错误
java.io.IOException: Content-Length and stream length disagree
Run Code Online (Sandbox Code Playgroud)
在这行代码上 return response.body().bytes();
这是完整的代码
编辑:在一些谷歌之后,错误的原因来自okhttp lib
if (contentLength != -1L && contentLength != bytes.size.toLong()) {
throw IOException(
"Content-Length ($contentLength) and stream length (${bytes.size}) disagree")
}
Run Code Online (Sandbox Code Playgroud)
但是如何解决这个问题?
编辑:
这是完整的代码:
public class OkHttpHandler extends AsyncTask<Void, Void, byte[]> {
private final String Fetch_URL = "http://justedhak.comlu.com/get-data.php";
ArrayList<Listitem> Listitem;
int resulta;
OkHttpClient httpClient = new OkHttpClient();
String myJSON;
JSONArray peoples = null;
InputStream inputStream = null;
@Override
protected byte[] doInBackground(Void... params) {
Log.d("e", "dddddddddd");
Log.d("e", Fetch_URL);
Request.Builder …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用okHTTP多部分将图像上传到服务器中.服务器不接受我的请求.我的问题是我在日志记录拦截器中看不到我的多部分,所以我无法调试.这是我使用的代码和生成的日志cat以及所需的有效负载.任何帮助表示赞赏.
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("uploaded_file", filename, RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
.addFormDataPart("flowChunkNumber", "1")
.addFormDataPart("flowCurrentChunkSize", String.valueOf(sourceFile.getTotalSpace()))
.addFormDataPart("flowChunkSize", "1048576")
.addFormDataPart("flowIdentifier", "4731-images1jpeg")
.addFormDataPart("flowFilename", "images (1).jpeg")
.addFormDataPart("flowFilename", "images (1).jpeg")
.addFormDataPart("flowRelativePath", "images (1).jpeg")
.addFormDataPart("flowTotalChunks", "1")
.build();
Request request = new Request.Builder()
.addHeader("cookie", ******* )
.url(URL_UPLOAD_IMAGE)
.post(requestBody)
.build();
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient
.Builder()
.addNetworkInterceptor(logInterceptor)
.build();
Response response = client.newCall(request).execute();
Run Code Online (Sandbox Code Playgroud)
这就是我在使用拦截器时在log cat中看到的内容
D/OkHttp: - > POST https://www.appido.ir/api/profile/avatar http/1.1
D/OkHttp:内容类型:multipart/form-data; 边界= a8028055-3a30-4942-916b-af56935e8b32
D/OkHttp:内容长度:14097 D/OkHttp:cookie:************************
Domain = .appido.ir; expires =星期二,2016年8月23日13:31:11 GMT; 路径= …
我正在使用okhttp并对我的一个应用程序进行改造,并且我有很多请求使用RxJava在不同的线程上工作.有时我在任何请求上都有SocketException,之后没有请求可以到达服务器.
例如,我可以分享一个样本.
我可以分享的代码中很少有修改过的代码段.
Subscription details = api.details("keyword")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Model>() {
@Override
public void onCompleted() {
Timber.d("onCompleted(): ");
}
@Override
public void onError(Throwable e) {
Timber.e(e, "onError(): ");
}
@Override
public void onNext(final Model details) {
Timber.d("onNext(): ");
}
});
Run Code Online (Sandbox Code Playgroud)
没有任何东西从3个回调中调用.
Stackstace:
11-17 15:50:53.991 16595-10314/ D/OkHttp: --> GET API_REQUEST_URL
11-17 15:50:53.991 16595-10314/ D/OkHttp: Host: HOST_NAME
11-17 15:50:53.991 16595-10314/ D/OkHttp: Connection: Keep-Alive
11-17 15:50:53.991 16595-10314/ D/OkHttp: Accept-Encoding: gzip
11-17 15:50:53.991 16595-10314/ D/OkHttp: User-Agent: okhttp/3.4.2
11-17 15:50:53.991 16595-10314/ D/OkHttp: User-Agent: Android-App …Run Code Online (Sandbox Code Playgroud) 我在android中使用okhttp库下载文件.我下载成功了.但是当我暂停并恢复下载时出现问题.
Response request = new Request.Builder().url(url).build();
ResponseBody responseBody = response.body();
File file = new File(filePath);
BufferedInputStream input = new BufferedInputStream(responseBody.byteStream());
OutputStream output;
if (isResume) {
output = new FileOutputStream(file, true);
input.skip(downloadedSize);
} else {
output = new FileOutputStream(file, false);
}
long totalByteSize = responseBody.contentLength();
byte[] data = new byte[1024];
int count = 0;
while ((count = input.read(data)) != -1) {
downloadedSize += count;
output.write(data, 0, count);
}
Run Code Online (Sandbox Code Playgroud)
问题是例如文件大小是10MB.下载3MB然后恢复下载时暂停,下载完成后文件大小变成13MB.它不是从恢复时的下载大小开始,它从字节流开始下载.所以文件变成13MB.代码有什么问题?
我需要能够 使用OKHTTP 管理一些请求,使用通过键入地址来接收一些预测.该问题是每当我插入时间CHAR它将使一个新的请求,但在同一时间,我需要取消前一个!例如:同时纽约市= 13个请求!所以我正在使用单个实例来尝试取消已经请求但没有成功的任何内容.这就是我做的!Google Places AutoCompleteCall
Address.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if(Address.getText().toString().length() > 3){
_Address = Address.getText().toString();
if(call != null){
call.cancel();
}
Request request = new Request.Builder()
.url(getPlaceAutoCompleteUrl(_Address))
.addHeader("content-type", "application/json")
.addHeader("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; google_sdk Build/MR1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30")
.build();
call = client.newCall(request);
call.enqueue(new Callback() {
public void onResponse(Call call, final Response response) throws IOException …Run Code Online (Sandbox Code Playgroud) 这是一个很长的故事,我会尽量提供尽可能多的细节。
几个月来,我一直在使用 android studio 3.xx 来构建我的应用程序,直到最近它开始为我提供最新的稳定版 4.0.1 的更新。
我更新了,它应该是无忧无虑的,所有插件都更新没有错误,代码首先在新的 android studio 中编译,该项目在测试中运行良好,然后我上传到 Play 商店的内部测试轨道(这里是问题开始)。
该应用程序开始在某些设备中显示某种锁定或无限循环错误......这很奇怪,因为运行调试版本时完全相同的设备很好,此时我认为有些proguard rules是问题所在。所以我调整了build.grade文件,以使debug构建具有与构建相同的设置release(缩小和缩小 TRUE)。
编译后,应用程序在模拟器和有问题的设备中顺利运行......
我再次将其上传到谷歌播放,并从那里下载该应用程序不起作用......
我做了一个非常详尽和烦人的代码调试,以获取以某种方式被锁定的方法,我发现了这个嫌疑人:
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.readTimeout(15000, TimeUnit.MILLISECONDS);
httpClientBuilder.writeTimeout(15000, TimeUnit.MILLISECONDS);
httpClientBuilder.connectTimeout(15000, TimeUnit.MILLISECONDS);
httpClientBuilder.retryOnConnectionFailure(true);
httpClientBuilder.followRedirects(true);
httpClientBuilder.followSslRedirects(true);
httpClientBuilder.connectionPool(DEFAULT_CONNECTION_POOL);
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(10);
dispatcher.setMaxRequestsPerHost(10);
httpClientBuilder.dispatcher(dispatcher);
okHttpClient = httpClientBuilder.build();
private boolean isInternetOK(){
boolean ret = false;
try {
okHttpClient.newCall(new Request.Builder().get().url("https://www.google.com").build()).execute();
ret true;
} catch (Exception e) {
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
在我的启动器活动中,在开始登录之前,我验证用户的 Internet 连接是否正常,这是一个简单的代码,并且httpclient …