Sending multiple requests using OkHTTP android - java

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
}

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.

Java-Android okhttpclient post request timeout

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());
}
});

How to correctly upload a video to server using okhttp client?

I am trying to upload a video to a server using okhttp client and although the onsuccess method is reached the video is not playable on the website.
My question is, am I uploading the video correctly using the storage path or am I missing something?
public void videoUploadTo(String url, String storageUrl) {
OkHttpClient client = new OkHttpClient();
File videoFile = new File(storageUrl);
Uri videoUri = Uri.fromFile(videoFile);
String content_type = getMimeType(videoFile.getPath());
RequestBody fileBody = RequestBody.create(MediaType.parse(content_type), videoFile);
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("type", content_type)
.addFormDataPart("uploaded_video", storageUrl.substring(storageUrl.lastIndexOf("/") + 1), fileBody)
.build();
Request request = new Request.Builder()
.url(siteUrl + url)
.put(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d("onfailure video", e.getMessage());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("onResponse video", response.message());
}
});
}
You can do something like this to create a Requestbody out of a FileInputStream:
final InputStream inputStream = new FileInputStream(videoFile);
final long fileSize;
fileSize = videoFile.length();
RequestBody requestBody = new RequestBody() {
#Override
public MediaType contentType() {
return MediaType.parse("video");
}
#Override
public long contentLength() throws IOException {
return fileSize;
}
#Override
public void writeTo(BufferedSink sink) throws IOException {
byte [] buffer = new byte[65536];
int bytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
sink.write(buffer, 0, bytesRead);
}
}
};
And then you can add that body as a part to your MultipartBody like this:
.addFormDataPart("video_file", videoFile.getName(), requestBody);

Get JSON with Cookie Android

If I log in on my website I get a cookie. That cookie is one year valid and I want it to implement in my Android application. With that cookie I can get JSON data and it works in Postman with the Interceptor extension.
But in Android I can't get it working. I tried it on many different ways:
Retrofit2:
public void GetCaregiver(){
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setSessionCookie("eyJpdiI6IjVcL1d6MEhLaGNZV3V2MFdVdFRtRVN3PT0iLCJ2YWx1ZSI6IldZWU42cUZQblcwejlDMk5LVllYOENXSThmVk9UUFIzaStxclZoUTFIRGlMazFlUzdjVDhFcTVxRllwMERncFFLZTVNQlQ0VUQ2SG5BSUE3TzJcL0Vrdz09IiwibWFjIjoiNDk3YmY3ZmE0NzA2Nzk1NzMwNTM0NDViOGNjNDllN2ZmZmYyNmNhNTdjNWYwOWYwYTIzZmI2YmI5OTc3OWZjNiJ9");
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(zorggemakURL)
.callFactory(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
RESTInterface service = retrofit.create(RESTInterface.class);
Call<List<Caregiver>> call = service.getCaregivers();
call.enqueue(new Callback<List<Caregiver>>() {
#Override
public void onResponse(Call<List<Caregiver>> call, retrofit2.Response<List<Caregiver>> response) {
Log.d("Response", response.toString());
}
#Override
public void onFailure(Call<List<Caregiver>> call, Throwable t) {
Log.d("Response", t.toString());
}
});
}
Volley:
public void GetCaregiver() {
// the request
String url = zorggemakURL + "api/user/overview";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// response
Log.d("Response", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
Log.d("ERROR", "error => " + error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
String creds = String.format("%s:%s", "orlandosmits", "test123");
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
headers.put("Cookie", cookie);
headers.put("Authorization", auth);
return headers;
}
};
Volley.newRequestQueue(context).add(request);
}
I will always get the HTML page back and not the JSON data. Anyone have an idea?
I got it working.
Final code:
public void GetCaregiver() {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new HeaderInterceptor()).build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(zorggemakURL)
.callFactory(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
RESTInterface service = retrofit.create(RESTInterface.class);
Call<List<Caregiver>> call = service.getCaregivers();
call.enqueue(new Callback<List<Caregiver>>() {
#Override
public void onResponse(Call<List<Caregiver>> call, retrofit2.Response<List<Caregiver>> response) {
List<Caregiver> caregivers = response.body();
String test = "";
}
#Override
public void onFailure(Call<List<Caregiver>> call, Throwable t) {
Log.d("Response", t.toString());
}
});
}
HeaderInterceptor class:
public class HeaderInterceptor implements Interceptor {
#Override
public Response intercept(Chain chain)
throws IOException {
Request request = chain.request();
request = request.newBuilder()
.addHeader("Cookie", "laravel_session=eyJpdiI6Im54UEpmbW9qdlc0a01FdG1uSGdNU3c9PSIsInZhbHVlIjoieGNuck96K0V2UWU1aG1vVE9DRDRQeWNQbEJ0UldEdWt2TUxFWjByVGVxckZ1a1NhcnE5dXMxTDBqTGtrcExQVEwzWkNQcTNSeHpUVXpFU3A5NHYxdEE9PSIsIm1hYyI6IjhlMzY0ODllYzEwOTFkNTYzZDU2ZmY1NTM5YTUyNmE0MTVlY2JmMjJkZDk0YmFiZmVhNDJmZDNkZmMwMTg5YWIifQ%3D%3D")
.build();
Response response = chain.proceed(request);
return response;
}

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