Upload list of objects to mysql using Retrofit Android - android

I have an ArrayList of custom objects, each with about 10 fields, that I already managed to upload to our server. The problem is that one of the fields is a String which contains a Base64-encoded string that I converted from a file, which the Retrofit Gson creater does not seem to like. This problem could be solved by just sending all the fields without the image, and then after that upload all the images using ftp, but it would be so much easier if I could just put the image in the object somehow.
Question: How can I send a Base64-encoded string as a field inside a custom object to a url using Retrofit?

#FormUrlEncoded
#POST("/UploadImages")
Call<ResponseBody> postImages(#Body ArrayListImage img);
//POJO CLASS
public class ArrayListImage {
#SerializedName("image")
#Expose
private ArrayList<String> image;
public ArrayListImage(ArrayList<String> image) {
this.image=image;
}
}

Below is the RequestBody code which i use to upload file using Retrofit:
RequestBody lRequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part lFile = MultipartBody.Part.createFormData("file", file.getName(), lRequestBody);
MultipartBody.Part title = MultipartBody.Part.createFormData("title", file.getName());
MultipartBody.Part lFilenamebase64 = MultipartBody.Part.createFormData("filenamebase64", base64EncodedFileName);
To encode file name:
String base64EncodedFileName = Base64.encodeToString(file.getName().getBytes(Charsets.UTF_8), Base64.URL_SAFE | Base64.NO_WRAP);
I defined the api like:
#Multipart
#POST("/upload")
Observable<Response<ResponseBody>> uploadFile(#Part MultipartBody.Part file, #Part MultipartBody.Part title, #Part MultipartBody.Part base64EncodedFileName);
I hope it might help you.

//Convert Object list into json string.
Gson gson = new Gson();
String objListString = gson.toJson(objectList);
#FormUrlEncoded
#POST("********")
Call<JsonObject> sendObjectList(#Field("objListString") String objListString);
And at the web end parse string into json.
#enjoy

Related

how to send List<String> with retrofit?

I'm sending a multipart request to server and this is my interface:
#Multipart
#POST("v1/group/new")
Call<MyResponse> newGroup(
#Header("token") String token,
#Part MultipartBody.Part photo,
#Part("title") RequestBody subject,
#Part("members") List<RequestBody> members);
and for sending my members in my fragment, I change my List<String> to List<RequestBody> as below:
List<RequestBody> members = new ArrayList<>();
for(int i = 0;i < membersId.size(); i++){
members.add(RequestBody.create(MediaType.parse("text/plain"),membersId.get(i)));
}
and it's working with multiple members! but when there is a one string in my list, retrofit doesn't sends my members as a list!!! for example:
I want to send array of strings like this :
["item1","item2","item3"]
my code works for this, but when there is only one item, retrofit sends this :
"item1"
instead of ["item1"]
what is the proper way of sending array of string in multipart with retrofit?
what am I doing wrong?
Use something like this.
#Multipart
#POST("v1/group/new")
Call<MyResponse> newGroup(
#Header("token") String token,
#Part MultipartBody.Part photo,
#Part("title") RequestBody subject,
#Part("members[]") List<RequestBody> members);
Remember you must add [] to your members param :).
#Multipart
#POST("v1/group/new")
Call<MyResponse> newGroup(
#Header("token") String token,
#Part MultipartBody.Part photo,
#Part("title") RequestBody subject,
#Part("members[]") ArrayList<RequestBody> members);
Two changes:
Change list to ArrayList as ArrayList is Serializable whereas List is not.
add "[]" at the end of the ArrayList type parameter.

How to upload images to the server using retrofit 2

I have to upload an image to server using Retrofit2.
Everything has worked fine at first, but after I re-check it before the release the API failed that can't upload the image but still works using postman!
My code is :
MultipartBody.Part imagePart = MultipartBody.Part.createFormData("image",
image.getFilename(), RequestBody.create(MediaType.get(image.getMimeType()), image.getFile()));
RequestBody sessionPart = RequestBody.create(MultipartBody.FORM, sessionToken);
RequestBody userIdPart = RequestBody.create(MultipartBody.FORM, userId);
RequestBody pictureTypePart = RequestBody.create(MultipartBody.FORM, pictureType.pictureTypeValue());
return dubaingNetwork.uploadProfilePic(accessToken,userIdPart,sessionPart,imagePart,pictureTypePart);
My api interface is:
#Multipart
#POST(Urls.UPLOAD_PROFILE_PIC)
Observable<UploadProfilePicResponse> uploadProfilePic(#Header(ACCESS_TOKEN_FIELD_NAME) String accessToken,
#Part(USER_ID_FIELD_NAME) RequestBody userId,
#Part(SESSION_TOKEN_FIELD_NAME) RequestBody sessionToken,
#Part MultipartBody.Part image,
#Part("image_type") RequestBody pictureType);
Edit: I tried to convert it to urlencoded type with the image converted to string Base64 and the parameters as a field but still the same error on phone and in postman still works, so I don't think it's a server-side error

is it possible to pass a single item as multipart using retrofit?

#Multipart
#POST("/api/add-deal/")
public void addDeal(#Body Deal deal, #Part("image")TypedFile image,Callback<Response> callback);
I want to send only the image as multipart and the rest as is.Is there any possible way ? Even I tried to add TypedFile inside my Deal model but unable to annotate with #part
Yes, it is possible with Partmap annotation using hash map. For example-
#Multipart
#POST("/api/add-deal/")
Call<Response> addDeal(#PartMap
HashMap<String, RequestBody> hashMap);
In hashMap you can add no of url parameters as key and set your values using RequestBody class type. see how to convert String and Image to RequestBody.
public static RequestBody ImageToRequestBody(File file) { //for image file to request body
return RequestBody.create(MediaType.parse("image/*"),file);
}
public static RequestBody StringToRequestBody(String string){ // for string to request body
return RequestBody.create(MediaType.parse("text/plain"),string);
}
add params to hashmap-
hashMap.put("photo",ImageToRequestBody(imageFile)); //your imageFile to Request body.
hashMap.put("user_id",StringToRequestBody("113"));
//calling addDeal method
apiInterface.addDeal(hashMap);
Hope this helpful.
It seems that you can send your #Body as TypedString.
For example, convert your "#Body Deal deal" into JSON String, and send it as TypedString.
Details: How to send multipart/form-data with Retrofit?
#Multipart
#POST("/api/v1/articles/")
Observable<Response> uploadFile(#Part("author") TypedString authorString,
#Part("photo") TypedFile photoFile);
This worked for me: POST Multipart Form Data using Retrofit 2.0 including image
public interface ApiInterface {
#Multipart
#POST("/api/Accounts/editaccount")
Call<User> editUser (#Header("Authorization") String authorization, #Part("file\"; filename=\"pp.png\" ") RequestBody file , #Part("FirstName") RequestBody fname, #Part("Id") RequestBody id);
}
File file = new File(imageUri.getPath());
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), firstNameField.getText().toString());
RequestBody id = RequestBody.create(MediaType.parse("text/plain"), AZUtils.getUserId(this));
Call<User> call = client.editUser(AZUtils.getToken(this), fbody, name, id);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(retrofit.Response<User> response, Retrofit retrofit) {
AZUtils.printObject(response.body());
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});

Retrofit - Combining Integer arraylist with Image file

Requirement is to upload image along with plain text and plain data has Arraylist of integers.
I am using #PartMap for plain data
For image part here is my code
imageFile = new File(imagePath);
imageBody = RequestBody.create(MediaType.parse("image/*"), imageFile);
multipartImageBody = MultipartBody.Part.createFormData("file_name", imageFile.getName(), imageBody);
For plain data
userIdBody = RequestBody.create(MediaType.parse("text/plain"), userId);
customerTypeBody = RequestBody.create(MediaType.parse("text/plain"), typeOfCustomer);
Combining plain data
HashMap<String, RequestBody> partMap = new HashMap<>();
partMap.put("userId", userIdBody);
partMap.put("customer_type", customerTypeBody);
The request
#POST<T> methodName(#PartMap Map<String, RequestBody> params, #Part MultipartBody.Part imageParam);
Issue occurs if i try to add integer listarray as Requestbody, the data is converted to string which server fails to parse rather we should be sending correct data from app side itself
What i tried
RequestBody.create(Mediatype,byte[])
Requestbody has this method which accepts our data as byte array,i converted arraylist to byte array but result was not as expected.
Is there any other possibility that i should try?
Converting from int[] to byte[] sounds like endianess issue. You should check in which endianess the server accepts the data and see if your conversion code is using the same endianess. You can use ByteBuffer to do the conversion, it has the order() method to specify endianess.
I haven't had any issues with retrofit's RequestBody.create myself, so I suspect this is the issue here.
Use it like this is the interface part
#Multipart
#POST("your/link")
Call<SuccessMessage> yourMethod(#Part MultipartBody.Part image,
#Part MultipartBody.Part[] data);//here you can use partmap also
and here is how it is used
MultipartBody.Part img = RequestHelper.multiPartBobyPart(image, "image");
MultipartBody.Part[] parts = new MultipartBody.Part[size];
for (int i = 0; i < size; i++) {
parts[i] = RequestHelper.multiPartBobyPart(yourStringArrayList.get(i), "var[]");
}
Call<SuccessMessage> call = mNetworkInterface.applyForDomesticJob(img, parts);
call.enqueue(this);
And here is the request helper class
public final class RequestHelper {
public static MultipartBody.Part multiPartBobyPart(java.io.File file, String parameterName) {
return MultipartBody.Part.createFormData(parameterName, file == null ? "noFile" : file.getName(),
RequestBody.create(MediaType.parse("multipart/form-data"), file == null ? new java.io.File("") : file));
}
public static RequestBody getRequestBody(String parameter) {
return RequestBody.create(MediaType.parse("multipart/form-data"), parameter);
}
public static MultipartBody.Part multiPartBobyPart(String data, String parameterName) {
return MultipartBody.Part.createFormData(parameterName, data);
}
}
use this link for more detailed information

Error End of input at line 1 column 1 path $ Retrofit

I want to upload data on server as well as audio file but i am getting the same error from last two days
here is my Interface
#Multipart
#POST("index.php")
Call<Result> uploadFile(#Part("client_phone") String phn,
#Part("call_type") String Ststus,
#Part("start_time") String Stime,
#Part("end_time") String Etime,
#Part MultipartBody.Part body,
#Part("employe_phone") String emphn);
And Here is My Retrofit Class
private static final String ROOT_URL ="http://192.168.0.113/recorder/api/";
public RetroClient() {
}
/**
* Get Retro Client
*
* #return JSON Object
*/
private static Retrofit getRetroClient() {
Gson gson = new GsonBuilder().setLenient().create();
return new Retrofit.Builder()
.baseUrl(ROOT_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
public static ApiService getApiService() {
return getRetroClient().create(ApiService.class);
}
And Here is the call to API
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("uploaded_file", file.getName(), requestFile);
Misscall ms=new Misscall("7276367824","IN","2016-12-12_12:12:12","2016-12-12_12:13:03","7276367824");
Gson gson=new Gson();
String json=gson.toJson(ms);
Log.i(MyApp.TAG, "Object Json"+ms);
//Call<Result> resultCall = service.uploadFile(map,body);
Call<Result> resultCall = service.uploadFile("7276367824","IN","123456","1234567",body,"7276367824");
Please help me
Thanks in advance
In my case this was happening only on the emulator (not all the time just in some cases). For some reason sometimes something was happening and the response that the server provides me came without its last char e.g. "}" and this caused the error. I don't know if this was caused by retrofit or something else. Could not reproduce it on real device tough.

Categories

Resources