Android Retrofit session - cookies - android

I am using retrofit to deserialize json request from web server and I need to create a session (cookie?) in my app (which should expire in 120 min). The problem is I don't know how to implement it.
private RestAdapter adapter = RestAdapter.Builder().setClient(????).setServer("http://192.168.0.1").build();
This session should persist only if the application is running.
Min SDK requirement is 8

Ok,you know the retrofit actually uses the okhttp inside the framework.
And you should know the "Interceptor"
When you init a okhttp in retrofit, you should invoke addInterceptor, just like this:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.retryOnConnectionFailure(true);
builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.addInterceptor(new ZCommonIntercepter());
Custom your own Intercepter extends Intercepter.
And get the sessionId by response.header("Set-cookie") save it as a Constant or something in your memory.
Every request after this you should remove the original header("cookie")
and addHeader (the thing that you have already saved)
I'm sorry that i'm not a native english speaker. If you can not understand me. I will just give you some keywords, you can google it.
---Key words---
interceptor in okhttp
cookies in request header or response header

Related

How to move to another activity after POST data with retrofit android?

I wanna ask something. So I have an activity to do registration for a new user. The flow for creating an account is that when a user fills the form and sends it to the server, then the server will check the data received whether it's already in the database or not. After that, if the data is new then the user confirmed as successfully registered and the apps will redirect the user to login activity. In this case, the data has been successfully inserted to the database but the logcat show me a line like this:
E/ViewRootImpl: sendUserActionEvent() returned
along with this:
D/EGL_emulation: eglMakeCurrent: 0x9ed852a0: ver 2 0 (tinfo 0x9ed831d0)
E/ERROR :: timeout
also, it didn't open the login activity even the data is successfully inserted.
Here is my ApiClient.java:
public class ApiClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String url){
if(retrofit == null){
retrofit = new Retrofit.Builder().baseUrl(url)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(new OkHttpClient().newBuilder()
.connectTimeout(3, TimeUnit.SECONDS)
.readTimeout(3, TimeUnit.SECONDS)
.writeTimeout(3, TimeUnit.SECONDS)
.build())
.build();
}
return retrofit;
}
}
Is there something that I missed? Cause when I try it just the basic ones, I mean like passing it through intent and no post action, it works. But when I try it along with POST action, the error thing comes out
Okay, I've figured out the solution. So basically in the server-side hasn't been registered to SMTP so it makes the connection request via client android become so slow. Therefore, I decided to try it first via the local server and it makes the client working perfectly fine. Nothing's wrong with the client code. Thank You for those who have read my issue. :D

How can I set connection timeout for OkHttpClient? 2017

It is easy to say it's duplicate but it isn't.
I read many post about how to set the connection timeout in android but the post are 4-7 years old and I think that we all need an update about this topic because those methods are deprecated or no longer exist.
So the question is how can I set my connection timeout when I am waiting for a response from the server?
final Response response = httpClient.newCall(request).execute();
if (response.isSuccessful()) {
//success
} else {
//unsuccessful
}
If you create your OkHttpClient through an OkHttpClient.Builder, there are connectTimeout(), readTimeout(), and writeTimeout() methods that you can call for the various timeout options.
If you need to override them for a specific HTTP request, call newBuilder() on your OkHttpClient. That gives you an OkHttpClient.Builder with the same settings as you used originally. You can override those as needed, and create a temporary OkHttpClient from the new Builder, using that for this one-off call.

MockRetrofit and BehaviorDelegate ignore the OkHttpClient

I'm writing an SDK for our MBaaS service. I use Retrofit2 for my REST calls.
I've an Interceptor (very similar to this) for refreshing an expired token that does a pretty complicated if-else cases. For testing the interceptor, I need to mock our API which I do using MockRetrofit library. So far so good! (See end of question for some info on my interceptor class)
Here's the code:
#Before
public void setup() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BacktoryClient.BASE_URL)
.client(new OkHttpClient.Builder().addInterceptor(new RetryWithRefreshedTokenInterceptor()).build())
.build();
NetworkBehavior behavior = NetworkBehavior.create();
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit)
.networkBehavior(behavior)
.build();
delegate = mockRetrofit.create(AuthApiDefinition.class);
}
#Test
public void testRetryWithRefreshedToken() throws Exception {
SimpleMock apiMock = new SimpleMock(delegate);
Response<SomeApiResponse> response = apiMock.someApiCall(<parameters>).execute();
// assert part
}
The problem is that response object in test method is what it should be (indication that mocking part is OK) but RetryWithRefreshedTokenInterceptor interceptor is not being called. So I assume that MockRetrofit ignores the OkHttpClient.
Now asking the real question, is this some kind of bug or I've completely misunderstood the usage of MockRetrofit library? If it was you, how you were testing the interceptor?
More info on RetryWithRefreshedTokenInterceptor: It checks if the response code is 401 or not and if so calls a method of our SDK which itself calls a method of our API (here from the mocked API) to get a new token and saves that in persistent storage (The amount of logic handled in API methods used in interceptor is big enough I can't isolate the interceptor to test it with MockWebserver)

How to cancel ongoing request in retrofit when retrofit.client.UrlConnectionClient is used as client?

I am using retrofit for http calls in my Android application and retrofit.client.UrlConnectionClient as the client while building the adapter.
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(url)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(
new Client.Provider() {
public Client get() {
return new UrlConnectionClient() {
#Override
protected HttpURLConnection openConnection(Request request)
throws IOException {
HttpURLConnection connection = super.openConnection(request);
connection.setConnectTimeout(connectionTimeout);
return connection;
}
I wanted to set the timeout so I have used UrlConnectionClient as my client. I could not find a way with other clients like OkHttp.
Question is : How can I cancel the ongoing request ?.
I have seen a similar post # Using Square's Retrofit Client, is it possible to cancel an in progress request? If so how? but my code would get really complex if I try to add my own executors and try to cancel the request using that. I am looking if there is slightly a better way with my existing code.
I also see that Retorofit V2.0 has plan for Retry and Cancel but not sure when that would be released..https://github.com/square/retrofit/issues/297
Need help !
In fact I also need a way to retry with the same code.
This has been available since 2.0.0-beta2 (https://github.com/square/retrofit/releases/tag/parent-2.0.0-beta2). I don't know if there is a doc that explains that but here is the link to API:
http://square.github.io/retrofit/2.x/retrofit/retrofit/Call.html#cancel--
'Call' API allows to do Retry as well by 'Clone'ing the request.

OkHttp - Enable logs

I used Retrofit in order to make HTTP requests and JSON parsing and I loved the way to turn on debug logs. Logs allow to see body requests, URL... which is very useful. As Retrofit use OkHttp, I'm wondering if OkHttp also have a way to enable logs for each requests made.
Using an Interceptor, you can define the following class:
class LoggingInterceptor implements Interceptor {
#Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Log.d("OkHttp", String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.d("OkHttp", String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
return response;
}
}
And add it:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
The interceptors feature is currently in review, but you can build your own version of okHttp with the feature by applying the code changes in the pull request.
You can implement the functionality you want with something like this
// Create an interceptor which catches requests and logs the info you want
RequestInterceptor logRequests= new RequestInterceptor() {
public Request execute(Request request) {
Log.i("REQUEST INFO", request.toString());
return request; // return the request unaltered
}
};
OkHttpClient client = new OkHttpClient();
List<RequestInterceptor> requestInterceptors = client.requestInterceptors();
requestInterceptros.add(logRequests);
A test is included within the pull request if you want to see more.
I'm going to have to warn you ahead of time about using this. There may be changes to the interceptor API since it has yet to be merged in. Don't use it with production code, but it's innocuous enough for personal testing.
None yet. But there's an interceptors feature under development that should make it easy.
There's an official solution from Square (employee) now.
You can try:
https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor
for okhttp3
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> Log.d(YourClass.class.getSimpleName(), "OkHttp: " + message));
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClient.getHttpClient().interceptors().add(logging);
you can enble logging and integerate with Timber to log only in debug.
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Timber.tag("OkHttp: ");
Timber.i(message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);
client = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.build();
I add some info regarding OkHttp3, because it supports logging out of the shelf.
First, be sure to have both these dependencies, the OkHttp3 main package and the specific package containing the logger implementations. Here I use 3.14.6.
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.6</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>3.14.6</version>
</dependency>
Then set up your OkHttp client properly.
...
import okhttp3.logging.HttpLoggingInterceptor;
...
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> logger.info(message));
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(interceptor)
.build();
The main idea is that you have to explain to the HttpLoggingInterceptor how to log, so in the above example the message is just routed to an Slf4j logger at INFO level.
For better ui and debugging of OkHttp Network calls you can use libraries like GANDER
Others features include :
Apps using Gander will display a notification showing a summary of ongoing HTTP activity. Tapping on the notification launches the full Gander UI. Apps can optionally suppress the notification, and launch the Gander UI directly from within their own interface. HTTP interactions and their contents can be exported via a share intent.
Search HTTP Activity and also request and response
The main Gander activity is launched in its own task, allowing it to be displayed alongside the host app UI using Android 7.x multi-window support.
Gander Provides following variants
Persistence : Saves logs to disk and TTL can be controlled
In Memory Database : Logs will be in memory as long as the app lifecycle.
No Op : This does nothing. So if users want Gander only in debug builds they can releaseCompile NoOp without dealing with variants, if(Build.DEBUG) ..etc
You can add logs by using:
public final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor())
.cache(new Cache(cacheDir, cacheSize))
.build();
Which will use default config:
Logger DEFAULT = message -> Platform.get().log(INFO, message, null);

Categories

Resources