Hello everyone I want to post image and other data through Retrofit2.
I am sending data with one image.
All the other info is storing but my image is not storing.while i am testing with postman, it works.
please guide me where I am lacking in my code
This is the postman code snippet that works
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\ntest6#gmail.com\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n123456\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTest\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"phone\"\r\n\r\n1234567890\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"03.JPG\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
Request request = new Request.Builder()
.url("https://"url"/api/v1/sign-up")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("cache-control", "no-cache")
.addHeader("postman-token", "2dd038d9-5f52-fcd0-9331-445eaf35c230")
.build();
Response response = client.newCall(request).execute();
Below is the postman request image:
this is my Retrofit api
#Multipart
#POST("sign-up")
Call<SignUpResponse> getSignUpResponse(
#Part("email") RequestBody email,
#Part("password") RequestBody password,
#Part("name") RequestBody name,
#Part("phone") RequestBody phone,
#Part MultipartBody.Part image
//#Part("image") RequestBody image // i have thried them both but they didnt work
//#Part("image\"; filename=\"pp.jpg\" ") RequestBody image
);
this is my client area:
private RetrofitClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging); // <-- this is the important line!
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
and this is the part where i am making the request:
RequestBody namePart = RequestBody.create(MultipartBody.FORM, "nameasd");
RequestBody emailPart = RequestBody.create(MultipartBody.FORM, "emailasd#gmai.com");
RequestBody mobilePart = RequestBody.create(MultipartBody.FORM, "123456623");
RequestBody passwordPart = RequestBody.create(MultipartBody.FORM, "123456123");
//String filepath = "/storage/0403-0201/DCIM/Camera/20180926_203219.jpg"; this is the image source
File file = new File(filepath);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image",file.getName(),reqFile);
Call<SignUpResponse> call = RetrofitClient.getInstance().getApi().getSignUpResponse(emailPart, passwordPart, namePart, mobilePart, body);
call.enqueue(new Callback<SignUpResponse>() {
#Override
public void onResponse(Call<SignUpResponse> call, Response<SignUpResponse> response) {
progressDialog.dismiss();
Log.d(TAG, "onResponse: "+response.body());
Log.d(TAG, "onResponse: meta: " + response.body().getMeta().getStatus());
}
#Override
public void onFailure(Call<SignUpResponse> call, Throwable t) {
Toast.makeText(SignupActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "onFailure: "+t.getMessage());
}
});
this is the code where i get the data
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// get selected images from selector
if (requestCode == REQUEST_CODE) {
if (resultCode == RESULT_OK) {
mResults = data.getStringArrayListExtra(SelectorSettings.SELECTOR_RESULTS);
imagePath = mResults.get(0);
Glide.with(SignupActivity.this)
.load(mResults.get(0))
.into(profileImage);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
I even set it on a view and that works...
We test api in Postman... So my Create Post Answer includes (all Dynamic)
Headers
Simple Strings
Single Image
Array Of Images
Array Of Categories
Array Of Features
Almost all things
Below is the Postman image for api testing...
Headers Image
So for this ...
Below is my Api...
#POST("post-create")
Call<PostCreateResponse> getPostCreateBodyResponse(
#Header("Accept") String accept,
#Header("Authorization") String authorization,
#Body RequestBody file
);
Now Retrofit Client area--->
private Retrofit retrofit;
// This is Client
private RetrofitClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.connectTimeout(100, TimeUnit.SECONDS);
httpClient.readTimeout(100,TimeUnit.SECONDS);
httpClient.writeTimeout(100,TimeUnit.SECONDS);
httpClient.addInterceptor(logging); // <-- this is the important line!
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
This is the way I Made the Request...
/*
* -------------- Retrofit post Create single featured Image Working with MultipartBody -----------
* */
progressDialog.show();
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("title", "3 room Current Free")
.addFormDataPart("location", "Dhaka")
.addFormDataPart("latitude", "23.7515")
.addFormDataPart("longitude", "90.3625")
.addFormDataPart("condition", "1")
.addFormDataPart("rent_amount", "123456")
.addFormDataPart("is_negotiable", "0")
.addFormDataPart("available_from", "2018-10-15");
// Categories
for (int categoryId : categories) {
builder.addFormDataPart("categories[]", String.valueOf(categoryId));
}
// Features
for (Integer featureId : features) {
builder.addFormDataPart("features[]", String.valueOf(featureId));
}
// featured Image
if (photoPaths.get(0) != null) {
File featured_image = new File(photoPaths.get(0));
if (featured_image.exists()) {
// If you want to use Bitmap then use this
Bitmap bmp = BitmapFactory.decodeFile(featured_image.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);
builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, bos.toByteArray()));
// If you want to use direct file then use this ( comment out the below part and comment the above part )
//builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, featured_image));
}
}
// Images
for (String photoPath : photoPaths) {
if (photoPath != null) {
File images = new File(photoPath);
if (images.exists()) {
builder.addFormDataPart("images[]", images.getName(), RequestBody.create(MultipartBody.FORM, images));
}
}
}
RequestBody requestBody = builder.build();
Call<PostCreateResponse> call = RetrofitClient.getInstance().getApi().getPostCreateBodyResponse(Accept, Authorization, requestBody);
call.enqueue(new Callback<PostCreateResponse>() {
#Override
public void onResponse(Call<PostCreateResponse> call, Response<PostCreateResponse> response) {
progressDialog.dismiss();
Log.d(TAG, "onResponse: response code: retrofit: " + response.code());
}
#Override
public void onFailure(Call<PostCreateResponse> call, Throwable t) {
}
});
/*
* ---------------- Retrofit post Create single featured Image Working with MultipartBody----------------
* */
I hope this will help you all... thanks
get Image like this
Uri mImageUri = data.getData();
// Get the cursor
Cursor cursor = getContentResolver().query(mImageUri,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageURI = cursor.getString(columnIndex);
cursor.close();
File file = new File(mImageUri.getPath())
RequestBody reqFile = RequestBody.create(okhttp3.MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image",
file.getName(), reqFile);
This is my activity code where i am using multipart to show images, follow this code:
public void uploadimage()
{
String filePath = getRealPathFromURIPath(uri1, DriverDetails.this);
Log.d("hanish123456","File path-> "+filePath);
file1 = new File(filePath);
Log.d("uploadimage", "Filename " + profileimage1);
Bitmap bmp = BitmapFactory.decodeFile(file1.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("image", profileimage1,
RequestBody.create(MediaType.parse("image/*"), bos.toByteArray()));
RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), profileimage1);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(3, TimeUnit.MINUTES)
.readTimeout(3,TimeUnit.MINUTES)
.writeTimeout(3,TimeUnit.MINUTES).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(SERVER_PATH)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService uploadImage = retrofit.create(ApiService.class);
Log.d("uploadimage", fileToUpload+" "+filename);
Call<ProfileResponse> fileUpload = uploadImage.uploadFile(fileToUpload, filename);
fileUpload.enqueue(new Callback<ProfileResponse>() {
#Override
public void onResponse(Call<ProfileResponse> call, Response<ProfileResponse> response) {
if(response.isSuccessful()){
Toast.makeText(DriverDetails.this,"Successful "+ response.raw().message(), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(DriverDetails.this, response.raw().message(), Toast.LENGTH_LONG).show();
}
// Toast.makeText(MainActivity.this, "Success " + response.body().getSuccess(), Toast.LENGTH_LONG).show();
Log.d("uploadimage", "No Error ");
}
#Override
public void onFailure(Call<ProfileResponse> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
Log.d("uploadimage", "Error occur " + t.getMessage());
}
}
});
}
there one more simple way to send other data, you can send Hashmap<String,String>
#Multipart
#POST("sign-up")
Call<SignUpResponse> getSignUpResponse(#Part MultipartBody.Part file, #PartMap() Map<String, String> partMap);
MultipartBody.Part.createFormData("file","fileName",RequestBody.create(okhttp3.MediaType.parse("image/*"), file))
Related
I am using retrofit 2 multipart for high quality Image upload (around 12 MB image). It works fine if I uses a Mobile Phone. But when I use Tablet it does not work. Can anyone tell me, what am I doing wrong here?
Here is my code:
public interface ApiDataService {
#Multipart
#POST("API Path Here")
Call<UploadImageResponse> Upload(#Header(Constants.KEY_AUTHORIZATION) String authorization,
#Part MultipartBody.Part file,
#Part("userId") RequestBody userId);
}
public class RetrofitInstance {
private static Retrofit retrofit = null;
public static Retrofit getInstance(){
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(100, TimeUnit.SECONDS)
.readTimeout(100,TimeUnit.SECONDS).build();
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Then I am using following method to Upload Image on server:
public void callUploadImageApi(String token, String fileName, String userId){
ApiDataService apiDataService = RetrofitInstance.getInstance().create(ApiDataService.class);
token = "Bearer "+ token;
File path = Environment.getExternalStorageDirectory();
File dir = new File(path.getAbsolutePath() + "/MyApplication/"+ fileName);
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(
MediaType.parse("image/*"),
dir
);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", dir.getName(), requestFile);
// add another part within the multipart request
RequestBody userIdString =
RequestBody.create(
okhttp3.MultipartBody.FORM, userId);
Call<UploadImageResponse> call = apiDataService.Upload(token, body, userIdString);
call.enqueue(new Callback<UploadImageResponse>() {
#Override
public void onResponse(Call<UploadImageResponse> call, Response<UploadImageResponse> response) {
if (response.body() != null) {
//success code here
}
}
#Override
public void onFailure(Call<UploadImageResponse> call, Throwable t) {
//failure code here
}
});
}
Thanks in advance for helping me...
I have a back end that I am able to upload a file to it by the following request in Pyhton:
data = {
"prop_post": 35
}
headers = {
# "Content-Type": "application/json",
"Authorization": "JWT " + t1,
}
if img_path is not None:
with open(img_path, 'rb') as image:
file_data = {
'photo': image
}
r = requests.post(POSTS_ENDPOINT, data=data,files=file_data, headers=headers)
that is my development environment. Now in production I am going to use Android as client to upload image. I am using Okhttp3. Here is the code that I am using to upload an image:
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpg");
String file2 = utils.getRealPathFromURI2(obj.getPhotos_uri()[0], context);
File file = new File(file2);
RequestBody req = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("prop-post", Integer.toString(id))
.addFormDataPart("photo", "IMG-20190705-WA0002.jpg",
// RequestBody.create(MEDIA_TYPE_PNG, file.getAbsolutePath())).build();
RequestBody.create(MEDIA_TYPE_PNG, file)).build();
Request request = new Request.Builder()
.url(root + "images/")
.addHeader("Authorization", header)
.post(req)
.build();
OkHttpClient client = new OkHttpClient();
Response response2 = client.newCall(request).execute();
This request doesn't go through with 400 (Bad request) response. My file absolute location in Android is : /storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20190705-WA0002.jpg
I appreciate if some one can tell me what I am doing wrong.
Thanks in advance
I ended up using retrofit:
added these dependencies in gradle:
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
then defined the following interface:
public interface ImageAPI {
#Multipart
#POST("images/")
Call<ResponseBody> createPost( #Part MultipartBody.Part file, #Part("prop_post") RequestBody requestBody);
}
then my post call looks like this:
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder
.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder newRequest = request.newBuilder().header("Authorization", "mytoken");
return chain.proceed(newRequest.build());
}
});
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(rootUrl)
.client(okHttpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
ImageAPI imageAPI = retrofit.create(ImageAPI.class);
String image_path = imagepath;//sets when browsing image
File file = new File(image_path);
RequestBody fileReqBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("photo", file.getName(), fileReqBody);
RequestBody id= RequestBody.create(MediaType.parse("text/plain"), "68");
Call<ResponseBody> call = imageAPI.createPost(part, id);
try {
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.d("tag", "onResponse: " + response.message().toString());
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("tag", "onResponse: " + t.getMessage());
}
});
} catch (Exception e) {
Log.d("tag", "onCreate: " + e.getMessage());
}
I am new to use Retrofit and I want to send byte array of any file to the server by i always get Failed response from server, and I successfully post file using Volley and HttpUrlConnection both. Now please help me, this is my code snippet .
public class ApiClientPost {
private static final String BASE_URL = "http://BASE.URL/api/";
private static Retrofit retrofit = null;
public static Retrofit getClient(){
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public interface ApiInterface {
#Multipart
#Headers({
"content-type: multipart/form-data"
})
#POST("eclaims/UploadFiles")
Call<JsonElement> UploadFiles(#Part MultipartBody.Part body);
}
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fin);
DataInputStream dis = new DataInputStream(bis);
fileContent = toByteArray(dis);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
MediaType mediaType = MediaType.parse("video/mp4");
RequestBody requestFile =
RequestBody.create(mediaType,
file
);
MultipartBody.Part body =
MultipartBody.Part.createFormData("", file.getName(),
requestFile);
ApiInterface apiInterface =
ApiClientPost.getClient().create(ApiInterface.class);
Call<JsonElement> uploadFile = apiInterface.UploadFiles(body);
uploadFile.enqueue(new Callback<JsonElement>() {
#Override
public void onResponse(Call<JsonElement> call,
Response<JsonElement> response) {
if (response.isSuccessful()) {
JsonElement mainResponse = response.body();
Log.d("Response ===", mainResponse.toString());
} else {
Log.e("Response ===", "Failed");
}
}
#Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Log.e("Failed ===", t.getMessage());
}
});
Sorry I am unable to give to URL. It have sensitive data. But i always get failed response from server when i convert a image or video file to byte array and send that byte array to server.
You don't need to convert it to file, you can pass the byte[] immediately.
public static MultipartBody.Part toMultiPartFile(String name, byte[] byteArray) {
RequestBody reqFile = RequestBody.create(MediaType.parse("video/mp4"), byteArray);
return MultipartBody.Part.createFormData(name,
null, // filename, this is optional
reqFile);
}
I'm trying to upload image on server using retrofit2 beta 3. In response i'm getting success but image is not getting uploaded on server. I dont know where's i'm making mistake.
and
Header Type is Content-Type: application/x-www-form-urlencoded
My Interface
#Multipart
#POST("/uploadFile")
Call<ResponseBody> upload(#PartMap Map<String, RequestBody> params);
and the method i used for uploading is
Method for uploading Image and data
private void uploadFile() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface service =
retrofit.create(ApiInterface.class);
File file = new File(fileUri.getPath());
Log.e(TAG, "uploadFile: " + file.toString());
String fileName = "uploadFile\"; filename=\"" + file.getName();
final RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
final RequestBody empsno = RequestBody.create(MediaType.parse("text/plain"), strEmpsno);
final RequestBody storsno = RequestBody.create(MediaType.parse("text/plain"), strStoreSno);
final RequestBody strlr = RequestBody.create(MediaType.parse("text/plain"), strLrno);
final RequestBody strtecq = RequestBody.create(MediaType.parse("text/plain"), strRecqty);
final RequestBody strtecv = RequestBody.create(MediaType.parse("text/plain"), strRecvol);
final RequestBody strtecw = RequestBody.create(MediaType.parse("text/plain"), strRecwgt);
final RequestBody strdmg = RequestBody.create(MediaType.parse("text/plain"), strDamageqty);
final RequestBody strlus = RequestBody.create(MediaType.parse("text/plain"), strLooseqty);
final RequestBody strdd = RequestBody.create(MediaType.parse("text/plain"), strDeliverydate);
final RequestBody strdt = RequestBody.create(MediaType.parse("text/plain"), strDeliverytime);
final RequestBody strrem = RequestBody.create(MediaType.parse("text/plain"), strRemarks);
final RequestBody strrec = RequestBody.create(MediaType.parse("text/plain"), strReceivedby);
final RequestBody strip = RequestBody.create(MediaType.parse("text/plain"), strIpaddress);
Map<String, RequestBody> oJSONObject = new HashMap<>();
oJSONObject.put("empsno", empsno);
oJSONObject.put("storesno", storsno);
oJSONObject.put("lrSno", strlr);
oJSONObject.put("recQty", strtecq);
oJSONObject.put("recVol", strtecv);
oJSONObject.put("recWgt", strtecw);
oJSONObject.put("damageQty", strdmg);
oJSONObject.put("looseQty", strlus);
oJSONObject.put("deliveryDate", strdd);
oJSONObject.put("deliveryTime", strdt);
oJSONObject.put("remarks", strrem);
oJSONObject.put("receivedBy", strrec);
oJSONObject.put("ipAddress", strip);
Call<ResponseBody> call = service.upload(oJSONObject);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.e(TAG, "onResponse: " + response.isSuccessful());
if (response.isSuccessful()) {
Log.e(TAG, "onResponse: " + response.body());
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getLocalizedMessage());
}
});
}
in response response.isSuccessful()=true. My response is getting successful then where is my problem. Please help me to find the solution.
Other way i also tried but not getting success, same result in another way also
#Multipart
#POST("/uploadFile")
Call<Response> getDetails(#Part("empsno") RequestBody empsno,
#Part("storesno")RequestBody storesno,
#Part("lrSno")RequestBody lrSno,
#Part("recQty")RequestBody recQty,
#Part("recVol")RequestBody recVol,
#Part("recWgt")RequestBody recWgt,
#Part("damageQty")RequestBody damageQty,
#Part("looseQty")RequestBody looseQty,
#Part("deliveryDate")RequestBody deliveryDate,
#Part("deliveryTime")RequestBody deliveryTime,
#Part("uploadFile\"; filename=\"abc.jpg\" ") RequestBody part,
#Part("remarks")RequestBody remarks,
#Part("receivedBy")RequestBody receivedBy,
#Part("ipAddress") RequestBody ipAddress
and method i used here is
File file = new File(fileUri.getPath());
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("uploadFile", file.getName(), requestFile);
RequestBody empsno = RequestBody.create(MediaType.parse("text/plain"), strEmpsno);
RequestBody storsno = RequestBody.create(MediaType.parse("text/plain"), strStoreSno);
RequestBody strlr = RequestBody.create(MediaType.parse("text/plain"), strLrno);
RequestBody strtecq = RequestBody.create(MediaType.parse("text/plain"), strRecqty);
RequestBody strtecv = RequestBody.create(MediaType.parse("text/plain"), strRecvol);
RequestBody strtecw = RequestBody.create(MediaType.parse("text/plain"), strRecwgt);
RequestBody strdmg = RequestBody.create(MediaType.parse("text/plain"), strDamageqty);
RequestBody strlus = RequestBody.create(MediaType.parse("text/plain"), strLooseqty);
RequestBody strdd = RequestBody.create(MediaType.parse("text/plain"), strDeliverydate);
RequestBody strdt = RequestBody.create(MediaType.parse("text/plain"), strDeliverytime);
RequestBody strrem = RequestBody.create(MediaType.parse("text/plain"), strRemarks);
RequestBody strrec = RequestBody.create(MediaType.parse("text/plain"), strReceivedby);
RequestBody strip = RequestBody.create(MediaType.parse("text/plain"), strIpaddress);
ApixInterface xInterface = retrofit.create(AudexInterface.class);
Call<Response> podResponsecall = xInterface.getDetails(empsno, storsno, strlr, strtecq,
strtecv, strtecw, strdmg, strlus, strdd, strdt,
requestFile, strrem, strrec, strip);
podResponsecall.enqueue(new Callback<Response>() {
#Override
public void onResponse(Call<Response> call, Response<Response> response) {
Log.e(TAG, "onResponse: " + response.isSuccessful());
if (response.isSuccessful()) {
Toast.makeText(getApplicationContext(), "Successfully saved!!!", Toast.LENGTH_LONG);
Log.e(TAG, "onResponse: " + response.body().getResult());
uploadFile();
}
}
#Override
public void onFailure(Call<Response> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getLocalizedMessage());
}
});
By using this method also response is successful but image not getting upload on server.
Thanks in advance
my solution is that:
first step.
#Multipart
#POST("Work/SendPic.ashx")
Observable<ImgBean> uploadImg(#Part MultipartBody.Part file);
second step.
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("img", file.getName(), requestBody);
UploadImg uploadImg = BaseRetrofit.getInstance().create(UploadImg.class);
and then, it is working.
What i have observed is there is some bug in Okhttp which does not upload image. Handle it like this:
#Multipart
#POST("api/chats/upload_chat_image")
Call<UploadChatItemResponse> getImageLink(
#Header("Authorization") String token,
#Part("productid") RequestBody productid,
#Part("touserid") RequestBody touserid,
#Part("image\";filename=\"image.*\" ") RequestBody image);
Notice the last part. You can create #PartMap for remaining items. But don't do it for files. Also, the first image in last part should be the key server is expecting while last image should be as it is.
RequestBody uploadImage = RequestBody.create(MediaType.parse("image/png"), compressed_image);
RequestBody productId = RequestBody.create(MediaType.parse("text/plain"), product.getProductid() + "");
RequestBody userId = RequestBody.create(MediaType.parse("text/plain"), otherUserInfo.getUserid() + "");
Call<UploadChatItemResponse> uploadChatImage = RestClient.getInstance(getApplicationContext()).getRestService()
.getImageLink(PrefUtils.getToken(ChatActivity.this), productId, userId, uploadImage);
uploadChatImage.enqueue(new Callback<UploadChatItemResponse>() {
#Override
public void onResponse(Call<UploadChatItemResponse> call, Response<UploadChatItemResponse> response) {
if (response.body() != null && response.body().imageLink != null) {
sendMessage(response.body().imageLink, new ChatItem.ChatType(false, ChatItem.ChatType.CHAT_TYPE_IMAGE, ChatItem.ChatType.CHAT_SUBTYPE_NO_SUBTYPE));
sweetAlertDialog.dismiss();
compressed_image.delete();
} else {
Toast.makeText(ChatActivity.this, "An error has occurred", Toast.LENGTH_SHORT).show();
sweetAlertDialog.dismiss();
compressed_image.delete();
}
}
#Override
public void onFailure(Call<UploadChatItemResponse> call, Throwable t) {
Toast.makeText(ChatActivity.this, "An error has occurred", Toast.LENGTH_SHORT).show();
sweetAlertDialog.dismiss();
compressed_image.delete();
}
});
Notice the type I have used while creating RequestBody for image.
Edit:
This is RestClient.java.
public class RestClient extends ContextWrapper {
private static final String BASE_URL = "https://www.restapi.in";
private APIService apiService;
private static RestClient restClient;
private static OkHttpClient okHttpClient;
private static final int READ_TIMEOUT = 100 * 1000;
private static final int CONNECTION_TIMEOUT = 100 * 1000;
private static final int CACHE_SIZE = 4;
private static final String CERTIFICATE_DOMAIN = "www.restclient.in";
private static final String[] CERTIFICATE_SHA = {"sha256/dkjabkjabcbakjbakjsbcabcahkcbakcbakcbakh=",
"sha256/ckjdcndkjcnjcnajcnajskcnakjcnakjcnaksjcna=",
"sha256/cjkacakjcbajcbasjkcbacjcbakcbcbakjbcjkacb="};
private RestClient(Context context) {
super(context);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getOkHttpClient(context))
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(APIService.class);
}
public static RestClient getInstance(Context context){
if(restClient==null)
restClient = new RestClient(context.getApplicationContext());
return restClient;
}
private static OkHttpClient getOkHttpClient(Context context){
if (okHttpClient == null) {
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(BuildConfig.DEBUG?HttpLoggingInterceptor.Level.HEADERS:HttpLoggingInterceptor.Level.NONE);
CertificatePinner.Builder certificatePinnerBuilder = new CertificatePinner.Builder();
for(String sha : CERTIFICATE_SHA)
certificatePinnerBuilder.add(CERTIFICATE_DOMAIN, sha);
okHttpClient = new OkHttpClient.Builder()
.cache(setCache(context))
.certificatePinner(certificatePinnerBuilder.build())
.retryOnConnectionFailure(false)
.readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
.connectTimeout(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("Content-type", "application/json")
.header("Accept", "application/json")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
})
.addInterceptor(logger)
.build();
}
return okHttpClient;
}
private static Cache setCache(Context context) {
int cacheSize = CACHE_SIZE * 1024 * 1024;
return new Cache(new File(context.getCacheDir(), "http"), cacheSize);
}
public APIService getRestService(){
return apiService;
}
}
Just remove Header Type
#headers({Content-Type: application/x-www-form-urlencoded})
What are my options for uploading a single large file (more specifically, to s3) in multipart in Android using OKhttp?
Get OkHttp 2.1, and use MultipartBuilder.addFormDataPart() which takes the filename as a parameter.
/**
* Upload Image
*
* #param memberId
* #param sourceImageFile
* #return
*/
public static JSONObject uploadImage(String memberId, String sourceImageFile) {
try {
File sourceFile = new File(sourceImageFile);
Log.d(TAG, "File...::::" + sourceFile + " : " + sourceFile.exists());
//Determining the media type
final MediaType MEDIA_TYPE = sourceImageFile.endsWith("png") ?
MediaType.parse("image/png") : MediaType.parse("image/jpeg");
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("member_id", memberId)
.addFormDataPart("file", "profile.png", RequestBody.create(MEDIA_TYPE, sourceFile))
.build();
Request request = new Request.Builder()
.url(URL_UPLOAD_IMAGE)
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
return new JSONObject(response.body().string());
} catch (UnknownHostException | UnsupportedEncodingException e) {
Log.e(TAG, "Error: " + e.getLocalizedMessage());
} catch (Exception e) {
Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
}
return null;
}
#Edited for okhttp3:
compile 'com.squareup.okhttp3:okhttp:3.4.1'
RequestBody replaced by:
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("uploaded_file", filename, RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
.addFormDataPart("result", "my_image")
.build();
#Uploaded Demo on GITHUB:
##I have added my answer for Multiple Image Upload :)
From the OkHttp Recipes page, this code uploads an image to Imgur:
private static final String IMGUR_CLIENT_ID = "...";
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
// Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"title\""),
RequestBody.create(null, "Square Logo"))
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\""),
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
.build();
Request request = new Request.Builder()
.header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}
You'll need to adapt this to S3, but the classes you need should be the same.
For okhttp 4.* use the MultipartBody.Builder:
fun postMultipart(url: String, text: String, imagePath: String, imageFileName: String): okhttp3.Response? {
val file = File(imagePath)
val fileRequestBody = file.asRequestBody("image/jpeg".toMediaType())
val requestBody = MultipartBody.Builder()
.addFormDataPart("text", text)
.addFormDataPart("image", imageFileName, fileRequestBody)
.build()
val request = getRequestBuilder(url)
.post(requestBody)
.build()
val client = OkHttpClient()
client.newCall(request).execute().use { response ->
return response
}
}
for okhttp 2.6.0 {
try {
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/xxx/share/" + "ic_launcher.png");
String contentType = file.toURL().openConnection().getContentType();
RequestBody fileBody = RequestBody.create(MediaType.parse(contentType), file);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("fileUploadType","1")
.addFormDataPart("miniType",contentType)
.addFormDataPart("ext",file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(".")))
.addFormDataPart("fileTypeName","img")
.addFormDataPart("Filedata","ss.png",fileBody)
.build();
Request request = new Request.Builder()
.url(Contains.MULTIPARTY_POST)
.post(requestBody)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
tvGetNews.setText("upload fail");
}
});
}
#Override
public void onResponse(Response response) throws IOException {
runOnUiThread(new Runnable() {
#Override
public void run() {
tvGetNews.setText("upload success");
}
});
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
In Android you usally part from an Uri. The problem when using large files is that you easily run into OutOfMemoryError if you try to read the full stream to a byte array (everything in memory) or you end up creating useless files with Uri stream. This is because RequestBody doesn't support creation from Stream (because sometimes OkHttp needs to read it many times, if you get a 30X redirect for instance) or Uri (because OkHttp is not an Android library).
But OkHttp provides the library Okio, with convenient classes emulating Streams (Source and Sink) and more convenient internal usage.
So, to create a BodyRequest form an Uri avoiding any OutOfMemoryError due to large files create it this way:
private static final MediaType MULTIPART_FOR_DATA = MediaType.parse("multipart/form-data");
private #NotNull RequestBody getFilePart(Uri largeFileUri) {
return new RequestBody() {
#Override
public MediaType contentType() {
return MULTIPART_FOR_DATA;
}
#Override
public void writeTo(#NotNull BufferedSink sink) throws IOException {
try (Source source = Okio.source(context.getContentResolver().openInputStream(mediaUri))) {
sink.writeAll(source);
}
}
};
}
Thank you to everyone posting and commenting in the folowing GitHub thread https://github.com/square/okhttp/issues/3585