Java-Android okhttpclient post request timeout - java

I do a post request an api running on my localhost but it throws TimeOut exception.
I set every timeout for 1 minutes but still getting error of timeout.
Here is my code for request :
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(1,TimeUnit.MINUTES)
.writeTimeout(1,TimeUnit.MINUTES)
.connectTimeout(1, TimeUnit.MINUTES)
.build();
RequestBody formBody = new FormBody.Builder()
.add("Username", "***")
.add("Password", "****")
.build();
HttpUrl localUrl = HttpUrl.parse("http://192.168.1.40:44338/api/authorize/login");
Request request = new Request.Builder()
.url(localUrl)
.addHeader("Content-Type","application/json")
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
System.out.println("y" + e.getMessage());
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
System.out.println("ccc :" + response.body().string());
}
});

Related

Okhttp Interceptor issue

I'm trying to add a header to a simple okhttp (Get) request. How do I add the HttpHeader properly? Can I debug to ensure that my Header is actually sent to the server?
Request request = new Request.Builder()
.url("URL")
.build();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request newRequest = originalRequest.newBuilder()
.addHeader("Header", "123")
.build();
return chain.proceed(newRequest);
}
})
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
I've looked for basic simple examples but they are with Retrofit, GSON, Interfaces, or in Kotlin. Need to understand it codewise.
You can use by method addHeader send chain as param and add headers.
Request getRequest = chain.request();
Request.Builder requestBuilder = getRequest.newBuilder()
.addHeader("Header", "123");
Request request = requestBuilder.build();
return chain.proceed(request);
You can also visit and look at the answers link1 and link2.
Here is the all-request Structure you can use.
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
};
OkHttpClient client = httpClient.build();
Request request = new Request.Builder()
.url("URL")
.addHeader("Header", "123")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Log.d("OKHTTP3", e.getMessage());
// You get this failure
runOnUiThread(() -> {
});
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
final String _body = response.body().string();
Log.d("OKHTTP3", _body);
runOnUiThread(() -> {
});
} catch (InterruptedIOException e) {
runOnUiThread(() -> {
// Or this exception depending when timeout is reached
});
}
}
});
To check your request and to add headers, you can use interceptors.
To add headers, (copied from gist):
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("User-Agent", "Your-App-Name")
.header("Accept", "application/vnd.yourapi.v1.full+json")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
}
OkHttpClient client = httpClient.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
To see your headers, you can use sample example provided here:
class LoggingInterceptor implements Interceptor {
#Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
return response;
}
}
Use addHeader() to add headers. header() sets the already added header name to the value.
Request newRequest = originalRequest.newBuilder()
.addHeader("Header", "123")
.build();
And to verify it's working correctly, you can use HttpLoggingInterceptor to log your network requests.

Sending multiple requests using OkHTTP android

I am sending multiple images using OkHTTP. Since all the requests are asynchronous, I cannot run my final call until all the requests are done. How can I achieve this in OkHTTP?
I need to run my RunFinalRequest() after all the images have been sent. What I tried is, I put the my RunFinalRequest() on OnResponse() but it sometimes doesn't go through even though there is a response. Is there a better way to do it?
Here is my code:
public void SendALL(){
OkHttpClient client = new OkHttpClient();
client.dispatcher().setMaxRequestsPerHost(50);
final MediaType MEDIA_TYPE = MediaType.parse("image/png");
for (int i = 0; i < images.size(); i++){
File sourceFile = new File(images.get(i).getImageURI());
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", images.get(i).getJobID())
.build();
Request request = new Request.Builder()
.url("xxxxxxxxxxx")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
if(signatures.size() > 0){
File sourceFile = new File(Uri.parse(signatures.get(0).getImageURI()).toString());
String newJobID = signatures.get(0).getJobID().concat("-signature");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", newJobID)
.build();
Request request = new Request.Builder()
.url("XXXXXXXXXXX")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
RunFinalRequest();
You may try following mechanism:
private int uploadedImageCount;
...
public void sendAll() {
uploadedImageCount = 0;
OkHttpClient client = new OkHttpClient();
client.dispatcher().setMaxRequestsPerHost(50);
MediaType MEDIA_TYPE = MediaType.parse("image/png");
for (int i = 0; i < images.size(); i++) {
File sourceFile = new File(images.get(i).getImageURI());
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", images.get(i).getJobID())
.build();
Request request = new Request.Builder()
.url("xxxxxxxxxxx")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
onImageUploadFailed();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
onImageUploaded();
} else {
onImageUploadFailed();
}
}
});
}
if (signatures.size() > 0) {
File sourceFile = new File(Uri.parse(signatures.get(0).getImageURI()).toString());
String newJobID = signatures.get(0).getJobID().concat("-signature");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", sourceFile.getName(), RequestBody.create(MEDIA_TYPE, sourceFile))
.addFormDataPart("name", newJobID)
.build();
Request request = new Request.Builder()
.url("XXXXXXXXXXX")
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
}
public void onImageUploaded() {
uploadedImageCount++;
if (uploadedImageCount == images.size()) {
runFinalRequest();
}
}
public void onImageUploadFailed() {
// Handle failure case. You may detect failed image and try to resend
}

Synchronous request failing HTTP

I am using okHTTP library to make an http request. It goes through but sometimes, my work in android progresses without complete response arrival. I realize this is happening because of the nature of my request being ASYNC.
OkHttpClient client = new OkHttpClient();
String url = "https://beta-pp-api.polkadoc.com/v1.0/products?category=CP&available_via=mail_order";
{
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", authentication.getToken())
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("X-Service-Code", "PP")
.get()
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e){
//do nothing!
}
#Override
public void onResponse(Response response) throws IOException
try {
jsonArray = new JSONArray(response.body().string());
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
I have tried calling
Response response = client.newCall(request).execute();
However, it fails because in Android we cannot call Sync request on main thread. leads to error NetworkOnMainThread android.os.
Is there a solution to this problem.
Do the process in a background thread something like below:
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
new AsyncTask<Void, Void, JSONArray>() {
#Override
protected JSONArray doInBackground(Void... voids) {
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", authentication.getToken())
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("X-Service-Code", "PP")
.get()
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return new JSONArray(response.body().string());
} else {
// notify error
}
} catch (IOException e) {
// notify error e.getMessage()
}
return null;
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
super.onPostExecute(jsonArray);
if (jsonArray != null && jsonArray.size() > 0) {
// notify status using LocalBroadcastManager or EventBus
}
}
}.execute();

Perform OkHttp network actions in background thread

I am using OKHttp to perform Post request to server, as follow:
public class NetworkManager {
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, JSONObject json) throws IOException {
try {
JSONArray array = json.getJSONArray("d");
RequestBody body = new FormEncodingBuilder()
.add("m", json.getString("m"))
.add("d", array.toString())
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (JSONException jsone) {
return "ERROR: " + jsone.getMessage();
}
}
}
and call it with:
NetworkManager manager = new NetworkManager();
String response = manager.post("http://www.example.com/api/", jsonObject);
When I try to run the App, it prompts an error in the logcat:
android.os.NetworkOnMainThreadException
at
android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
With reference to other questions in SO, I added this to override the policy:
if (android.os.Build.VERSION.SDK_INT > 9)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Yet I think this is unhealthy and I would like to put the NetworkManager actions to background. How can I do so?
Since OkHttp supports async way too, so IMO you can refer to the following GET request sample, then apply for your POST request:
OkHttpClient client = new OkHttpClient();
// GET request
Request request = new Request.Builder()
.url("http://google.com")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
Log.e(LOG_TAG, e.toString());
}
#Override
public void onResponse(Response response) throws IOException {
Log.w(LOG_TAG, response.body().string());
Log.i(LOG_TAG, response.toString());
}
});
Hope it helps!

How to use OkHttp's HttpUrl with a request?

I have an http url:
HttpUrl httpurl = new HttpUrl.Builder()
.scheme("https")
.host("www.google.com")
.addPathSegment("search")
.addQueryParameter("q", "polar bears")
.build();
How do I use that with a request? That is, how do I send a request to the url constructed by httpurl?
Use Request.Builder#url(HttpUrl):
Request r = new Request.Builder()
.url(httpurl).build();
Then follow here.
Try this:
Request request = new Request.Builder()
.method(method, requestBody)
.url(httpurl)
.addHeader(headerName, headerValue);
.build();
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
}
#Override
public void onResponse(Response response) throws IOException {
}
});

Categories

Resources