How to Post multiple image using OkHttpClient in android studio java? - java

I need to send multiple files from android app
I have already succeeded sending the single file but I need to send multiple
my request body
RequestBody form = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("user_id", user_id)
.addFormDataPart("title", title)
.addFormDataPart("description", description)
.addFormDataPart("price", price)
.addFormDataPart("offer_price", offer_price)
.addFormDataPart("amenities", amenities)
.addFormDataPart("type", type)
.addFormDataPart("status", "1")
.addFormDataPart("file", user_id + ".JPG", RequestBody.create(MEDIA_TYPE_PNG, bytarray))
.addFormDataPart("file1", user_id + "1.JPG", RequestBody.create(MEDIA_TYPE_PNG, bytarray1))
.addFormDataPart("file2", user_id + "2.JPG", RequestBody.create(MEDIA_TYPE_PNG, bytarray2))
.build();
post url
String url = path.URL + path.CREATE_POST_API;
Request request = new Request.Builder()
.url(url)
.post(form)
.build();
Okhttp execute
try (Response response = okHttpClient.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
// System.out.println(response.body().string());
Log.d("runPost: ", response.body().string());
} catch (IOException e) {
e.printStackTrace();
}

Related

I got different results when call simple GET Request with curl and java okhttp

I call below URL using cURL
curl 'http://username:password#192.168.1.108/merlin/Login.cgi'
and I get proper response
{ "Session" : "0xb3e01810", "result" : { "message" : "OK", "num" : 200 } }
I get the same response from browser (directly open link), postman and even with NodeJs,
but I get response code 401 when send GET_Request to this url using okhttp in java
my java code with okhttp is
Request request = new Request.Builder()
.url("http://username:password#192.168.1.108/merlin/Login.cgi")
.build();
try {
com.squareup.okhttp.Response response = client.newCall(request).execute();
System.out.println(response.code());
} catch (IOException e) {
e.printStackTrace();
}
Use basic authentication. Having username and password in the url, separated with :, is the same as basic authentication. I tested and it's ok. my snippet is:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://192.168.1.108/merlin/Login.cgi")
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString("username:password".getBytes()))
.get().build();
try (Response response = client.newCall(request).execute()) {
assert response.body() != null;
String res = response.body().string();
} catch (Exception e) {
e.printStackTrace();
}

okhttp call paybylink bad request but it does work in postman

I am trying to connect to pay by link by json.
We first tried with json and it worked like a charm.
I used the code postman provided to create this,
But we keep getting 400 bad request,
If we change the credentials we get unauthorized, se wo know it's not that
But if we go look in the request log of pay by link we see that the request send from java does not appear here at all, it does not show error, but nothing.
Does anybody know how we can fix it?
Thanks in advance!
Sincerely,
Laurens
try {
OkHttpClient client = new OkHttpClient();
client.setConnectionSpecs(Arrays.asList(
new ConnectionSpec[]{
new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.allEnabledCipherSuites()
.build()
}
));
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"MappingTemplate\":\"test1\", \r\n\"OrderId\":\"NFA000053\",\r\n\"Description\":\"test#123.com\",\r\n\"Amount\":50,\r\n\"Gender\":\"Male\",\r\n\"Clientname\":\"Test\",\r\n\"Send\":\"nosend\"\r\n}");
Request request = new Request.Builder()
.url("https://testapi.paybylink.com/payment/create/abcdefghijkl.../")
.post(body)
.addHeader("Content-Type","application/json")
.addHeader("Authorization", credential)
.build();
Response response = client.newCall(request).execute();
System.out.println("request: " + request);
if(response.code()==400)
{
System.out.println("response: " + response);
}
} catch (Exception e) {
System.out.println("Exception occurred:- " + e.getMessage());
}

Uploading File with okhttp 3.9.0 to REST is giving Error code=422, message=Uprocessable Entity

I'm trying to upload a file to a REST-Service via okhttp3 (3.9.0).
It does not work and I got the error: ** code=422, message=Unprocessable Entity**
but I can't find my error ...
Here is my code:
private void test_OK_HTTP() {
String userCredentials = "username:password";
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
File f = new File("C:\\history48.png");
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("DocumentName", "file.png")
.addFormDataPart("FK_Person", "1d64b9cc-d405-47c4-9adb-ef276c391ae0&")
.addFormDataPart("FK_FileManagerFormKey", "33")
.addFormDataPart("SystemFileType", "368")
.addFormDataPart("Subject", "test")
.addFormDataPart("SubjectDate", "2022-02-24")
.addFormDataPart("DocumentContent", "file.png", RequestBody.create(MediaType.parse("image/png"), f))
.build();
Request request = new Request.Builder()
.url("http://myurlthatworksfine/RestServiceTest/AddNewDocument")
.addHeader("api-version", "v1")
.addHeader("Authorization", basicAuth)
.post(requestBody)
.build();
System.out.println("Request: "+request.body().toString());
try {
Response response = client.newCall(request).execute();
System.out.println("Response: " + response.toString());
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error: "+e);
}
}
Has any one any idea what I'm doing wrong?
Thanks.
I had a simple error in my test-id ... it works now ... :)
WRONG:
.addFormDataPart("FK_Person", "1d64b9cc-d405-47c4-9adb-ef276c391ae0&")
OK:
.addFormDataPart("FK_Person", "1d64b9cc-d405-47c4-9adb-ef276c391ae0")

Microsoft graph : Updating a document with a Put request Java

Based on the MS graph documentation, I saw that i can update a driveItem (file) and put it in a specific sharepoint drive. The application is running as a daemon application (without user login).
For this I use this entry point :
PUT /drives/{drive-id}/items/{item-id}/content
I try to code using a main class and passing existing parameters. To update a document I call a method update document :
UpdateDocumentResponseModel updatedDocument = fileGraphs.updateDocument(token, DRIVELIBID, DOCUMENTID, INPUTPATH, DOCUPDATE);
The called method aims to build the URL and prepare the datas for the PUT request :
public UpdateDocumentResponseModel updateDocument(String accessToken,
String driveLibId,
String documentId,
String inpuPath,
String docName) throws MalformedURLException {
String fullPath = inpuPath + docName;
URL url = new URL("https://graph.microsoft.com/v1.0/drives/" + driveLibId + "/items/" + documentId + "/content");
return requestsBuilder.updateDocument(accessToken, url, fullPath);
}
Now at this stage I have to make the request:
public UpdateDocumentResponseModel updateDocument(String accessToken, URL url, String fullPath) {
UpdateDocumentResponseModel returnValue = new UpdateDocumentResponseModel();
try {
CloseableHttpClient client = HttpClients.createDefault();
HttpPut httpPut = new HttpPut(String.valueOf(url));
httpPut.setHeader("Authorization", "Bearer " + accessToken);
httpPut.setHeader("Accept","application/json");
httpPut.setHeader("Content-Type","plain/text");
httpPut.setHeader("Connection", "Keep-Alive");
httpPut.setHeader("Cache-Control", "no-cache");
// read the file and convert to stream
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", new File(fullPath),
ContentType.APPLICATION_OCTET_STREAM, "file.ext");
HttpEntity multipart = builder.build();
httpPut.setEntity(multipart);
CloseableHttpResponse response = client.execute(httpPut);
System.out.println("\nSending 'UPDATE' request to URL : " + url);
System.out.println("Response Code : " + response.getStatusLine());
// set the response
returnValue.setDocumentName(fullPath);
returnValue.setUpdatedAt(new Date());
returnValue.setUpdateStatus("Success");
} catch (IOException e) {
returnValue.setDocumentName(fullPath);
returnValue.setUpdatedAt(new Date());
returnValue.setUpdateStatus("Failure" + e.getCause());
e.printStackTrace();
}
return returnValue;
}
My issue is that when I send back a docx file, this file is not correctly uploaded. The file is uploaded (good stuff) but is not readable in the sharepoint online portal and must be downloaded.
My second issue is that I can take any kind of file : doc, docx, ppt, xls, xlsx, txt, images...
I do think that I will encounter other issues. Is there a lib that could help me to handle file extension and correctly convert files. My issue is that I won't have to handle specifically MS Office files but any types.
My issue is obviously here :
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", new File(fullPath),
ContentType.APPLICATION_OCTET_STREAM, "file.ext");
HttpEntity multipart = builder.build();
httpPut.setEntity(multipart);
CloseableHttpResponse response = client.execute(httpPut);
Thanks !
I finally solved the issue by using ByteArrayInputStream...
I replaced :
// read the file and convert to stream
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", new File(fullPath),
ContentType.APPLICATION_OCTET_STREAM, "file.ext");
HttpEntity multipart = builder.build();
httpPut.setEntity(multipart);
with this:
byte[] fileContent = FileUtils.readFileToByteArray(new File(fullPath));
httpPut.setEntity(new InputStreamEntity(new ByteArrayInputStream(fileContent), fileContent.length));
Finally my method looks like this :
public UpdateDocumentResponseModel updateDocument(String accessToken, URL url, String fullPath) {
UpdateDocumentResponseModel returnValue = new UpdateDocumentResponseModel();
try {
CloseableHttpClient client = HttpClients.createDefault();
HttpPut httpPut = new HttpPut(String.valueOf(url));
httpPut.setHeader("Authorization", "Bearer " + accessToken);
httpPut.setHeader("Content-Type", "text/plain");
httpPut.setHeader("Connection", "Keep-Alive");
httpPut.setHeader("Cache-Control", "no-cache");
byte[] fileContent = FileUtils.readFileToByteArray(new File(fullPath));
httpPut.setEntity(new InputStreamEntity(new ByteArrayInputStream(fileContent), fileContent.length));
// httpPut.setEntity(new StringEntity(String.valueOf(in), StandardCharsets.UTF_8));
CloseableHttpResponse response = client.execute(httpPut);
System.out.println("\nSending 'PUT' request to URL : " + url);
System.out.println("Response Code : " + response.getStatusLine());
// set the response
returnValue.setDocumentName(fullPath);
returnValue.setUpdatedAt(new Date());
returnValue.setUpdateStatus("Success");
} catch (IOException e) {
returnValue.setDocumentName(fullPath);
returnValue.setUpdatedAt(new Date());
returnValue.setUpdateStatus("Failure" + e.getCause());
e.printStackTrace();
}
return returnValue;
}

How to get HTTP Response Error Code Doing OkHttp Sync Requests

I'm using OkHttp with Retrofit to do synchronized requests. The problem is that OkHttp throws an exception. I can catch the exception in the interceptor instead, but the response is null.
I'd like to display messages to the user based on HTTP response codes.
Response<List<Employee>> owner = null;
Call<List<Employee>> webCall = getWebService().getDeviceOwner("tolower(LoginId) eq tolower(\'" + SharedData.AuthorizationUserName + "\')");
try {
owner = webCall.execute();
if(isHttpResponseSuccess(owner.code())) {
Employee employee = owner.body().get(0);
}
else {
Log.e(TAG_NAME, "GetDeviceOwner() call failed. Http code=" + owner.code() + "/nMessage=" + owner.message());
}
catch (Exception e) {
//Some type of network error. 401, etc? I have no clue.
Log.e(TAG_NAME, "GetDeviceOwner() exception=" + e);
}
Client Interceptor
_okHttpClient = new OkHttpClient.Builder()
.addInterceptor(
new Interceptor() {
#Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Content-Type", "Application/JSON")
.addHeader("Authorization", "Basic " + new String(Base64.encode((SharedData.AuthorizationUserName + ":" + SharedData.AuthorizationPassword).getBytes(), Base64.NO_WRAP)))
.removeHeader("charset")
.build();
okhttp3.Response response = chain.proceed(request);
Log.d(TAG_NAME, "Response code="+ response.code());
Log.d(TAG_NAME, "Response="+ response.toString());
return response;
}
}).addInterceptor(logging).build();
u can test this code , when the response isn't 2xx it will worked that u can get the code with e.getMessage();
_okHttpClient = new OkHttpClient.Builder()
.addInterceptor(
new Interceptor() {
#Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Content-Type", "Application/JSON")
.addHeader("Authorization", "Basic " + new String(Base64.encode((SharedData.AuthorizationUserName + ":" + SharedData.AuthorizationPassword).getBytes(), Base64.NO_WRAP)))
.removeHeader("charset")
.build();
okhttp3.Response response = chain.proceed(request);
if (response.code()/100!=2){
throw new IOException(response.code()+"");
}
Log.d(TAG_NAME, "Response code="+ response.code());
Log.d(TAG_NAME, "Response="+ response.toString());
return response;
}
}).addInterceptor(logging).build();
You can use HttpResponse class
HttpResponse httpResponse = client.newCall(request).execute();
httpResponse.getStatusLine().getStatusCode();
If you are using com.squareup.okhttp.Response then you can use the code() method.
Response httpResponse = client.newCall(request).execute();
httpResponse.code();

Categories