java.io.IOException when using Retrofit with rxandroid - android

I need to make HTTP DELETE request to my server with body provided.
I build the retrofit object in the following way:
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES)
.build();
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new GsonUTCDateAdapter())
.registerTypeAdapter(LocalDate.class, new GsonLocalDateAdapter())
.create();
return new Retrofit.Builder()
.baseUrl(AppConfig.API_BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
My Retrofit service method is:
#HTTP(method = "DELETE", path = "selfie/{publicId}/action/1", hasBody = true)
Observable<SimpleResponseModel> unlike(
#Path("publicId") String publicId,
#Body AuthorisedRequestModel model
);
I handle retrofit request/response in following way:
NetworkHelper
.getRetrofit()
.create(SelfieService.class)
.unlike(selfieModel.getPublicId(), new AuthorisedRequestModel())
.subscribeOn(Schedulers.io())
.subscribe(new CustomSubscriber<SimpleResponseModel>() {
#Override
public void onNext(SimpleResponseModel simpleResponseModel) {
ErrorHelper.handleServerError(simpleResponseModel);
}
});
I should mention, that all another requests GET,POST and PUT are working, but all DELETE requests are return me following error, from log:
HTTP FAILED: java.io.IOException: unexpected end of stream on okhttp3.Address#c6ec992c
So the request don't reach the server.
When I used Retrofit without rxandroid and made queries in AsyncTasks everything worked well.
Caused by:
Caused by: java.io.EOFException: \n not found: size=0 content=…
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:215)
at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:186)

It is an issue. You can see it on GitHub:
https://github.com/square/okhttp/issues/1517

Related

Retrofit add Okhttp interceptor no use

I found something strange when I add interceptor like this:
public ApiDefinition getService() {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(chain -> {
System.out.println("into interceptor");
Request request = chain.request();
return chain.proceed(request);
})
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
return retrofit.create(ApiDefinition.class);
}
Then when I do call a network, nothing print just like the interceptor did't work.
Observable observable = apiDefinition.getResponse();
observable.subscribe(....)
I am confused, was there anything wrong?
apiDefinition.getResponse(); you forgetting to subscribe api call. Just getting observable, but not observing it.
apiDefinition
.getResponse()
.subscribe(.......);
if you want to intercept Network request call and print them in logcat
you can do so by adding an HttpLoggingInterceptor like that:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();
Sorry guys, i make some mistakes when i user dagger2 to inject ApiDefinition, so this is solved.

how to set retrofit connections timeout unlimited?

I want to set Retrofit connection timeout unlimited instead of static timeout
connection.how can I do it ?
This is my code...
public static Retrofit getRetrofitInstance() {
if (RetrofitInstance==null) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(100, TimeUnit.SECONDS)
.connectTimeout(100, TimeUnit.SECONDS)
.build();
RetrofitInstance = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okHttpClient)
.build();
}
return RetrofitInstance;
}
Retrofit does not allow developers to remove timeout completely, but you could set TimeUnit.HOURS to use big value for your timeout. For example:
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(Integer.MAX_VALUE, TimeUnit.HOURS)
.connectTimeout(Integer.MAX_VALUE, TimeUnit.HOURS)
.build();
Used Integer.MAX_VALUE for this example, which is big enough value to act as an infinite timeout.
Good luck :)

Execute service with retrofit 2 sending data in header

I am learning to use retrofit, to consume Webservices, I have no problems in executing the #GET, #POST methods but now I have to execute a service where the token is sent, I really do not know how to do it, but I use POSTMAN where this field token I send from Headers in the Authorization key. I have seen other examples where OkHttpClient is used but I can not think of how to implement it.
So I execute my service with retrofit, to this same one the token in the head should be sent to him.
#GET(Constants.Retrofit.SURE_DO_YOU_LIKE_PRODUCTS)
Call<List<RelatedProducts>> getProductSureDoYouLike();
and this is my service in POSTMAN.
Like this:
#GET(Constants.Retrofit.SURE_DO_YOU_LIKE_PRODUCTS)
Call<List<RelatedProducts>> getProductSureDoYouLike(#Header("Content-Type") String contentType, #Header("Authorization") String auth);
If all requests require a Content-Type you could modify your Retrofit builder to include the header on every request:
OkHttpClient client;// = new OkHttpClient();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES)
.addInterceptor(chain -> {
Request request = chain.request().newBuilder()
//Add this to include header in every request
.addHeader("Content-Type", "application/json").build();
return chain.proceed(request);
}).build();
client = builder.build();
retrofit = new Retrofit.Builder()
.baseUrl(NetworkConstants.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
Then your request would be:
#GET(Constants.Retrofit.SURE_DO_YOU_LIKE_PRODUCTS)
Call<List<RelatedProducts>> getProductSureDoYouLike(#Header("Authorization") String auth);
You would then call like so:
apiService.getProductSureDoYouLike("token");

Retrofit2 and Gson not have response in logcat

I try to get json from Retrofit2 (Retrofit 2.1.0) and Gson. But response body is not have. No in on onFailure. Pls help me.
add this in your gradle
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
Retrofit
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(logger)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(RETROFIT_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();

Retrofit2 SSLHandshakeException

I use Retrofit2. Requests are no execute after adding on server side SSL. The method onFailure get next Throwable - javax.net.ssl.SSLHandshakeException: Connection closed by peer.
Initialization Retrofit:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(InterfaceAPI.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
clientBuilder.connectTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS);
client = clientBuilder.build();
Then use this client for retrofit

Categories

Resources