okhttp request / multipart image - android

Ok, before you start saying that it's a duplicate and so on...
I have tried all ways I found on slack / documentations and it didn't help me out at all...and I just can't figure out what the problem is
So, these are last 2 ways I tried to make the request
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
//RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), loadImageFile);
//MultipartBody.Part filePart = MultipartBody.Part.createFormData("picture", loadImageFile.getName(), reqFile);
//RequestBody filename =
RequestBody.create(MediaType.parse("text/plain"),loadImageFile.getName());
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"),
loadImageFile);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file",
loadImageFile.getName(), requestBody);
The commented parts is a way, and the other lines is the way I am doing it now..
Here I have the interface
#Multipart
#POST(RestClient.API_REGISTER_URL)
Call<ResponseBody> register(#Query("name") String name, #Query("email") String email,
#Query("password") String password, #Query("location") String location,
#Query("latitude") double latitude, #Query("longitude") double longitude,
#Query("gender") String gender, #Part MultipartBody.Part picture,
#Part("picture") RequestBody file,
#Query("device_uuid") String device_uuid, #Query("device_os") String device_os,
#Query("push_token") String push_token, #Query("api_key") String user);
To be honnest, I simply can't figure out why it is not working..the response body from the server is "The picture must be an image" which makes me think that somehow it doesn't recognise the file I am sending
Any help would be apreciated, thanks .
EDIT
I changed the code a lil bit, another way I was trying to make it, and still something is not ok with this request...
RequestBody req = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("picture", loadImageFile.getName(), RequestBody.create( MultipartBody.FORM, loadImageFile))
.build();
MultipartBody.Part part = MultipartBody.Part.createFormData("picture", loadImageFile.getName(), req);

I'm using this code to send image to server with okhttp
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
RequestBody req = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("branchCode", branchCode)
.addFormDataPart("upload", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, file)).build();
Request request = new Request.Builder()
.url(URLs.UPLOAD_FILE)
.post(req)
.build();
Maybe problem occurs in your server side ?

Related

Retrofit java.lang.illegalStateException:Expected a string but was BEGIN_ARRAY at line 1 column 591

I am hitting an api with put request and pass Multipart data. Here is my interface:
#Multipart
#PUT("profile")
Call<ProfileSetupResponse> vendorProfile1(
#Header("access-token") String token,
#Part("businessName") RequestBody businessName,
#Part("step") RequestBody step,
#Part MultipartBody.Part image,
#Query("categories[]") List<String> categories,
#Part("country") RequestBody country,
#Part("contact") RequestBody contact,
#Part("aboutUs") RequestBody aboutUs,
#Part("businessDetail") RequestBody businessDetail,
#Part("businessEmail") RequestBody businessEmail,
#Query("tags[]") List<String> tags
);
I am getting the "java.lang.illegalStateException:Expected a string but was BEGIN_ARRAY at line 1 column 591" exception in the response from server.
Here is my method to pass data to server:
Call<ProfileSetupResponse> call = RetrofitClient.getInstance().getApi().vendorProfile1("Token",
bName, bStep, filePart, categories, bCountry, bContact, bAboutUs, bDetail, bEmail, tags);
Here Categories and Tags are ArrayList<>.
I am new to working with Retrofit please someone help.
Update to Question:
RequestBody bName = RequestBody.create(MediaType.parse("text/plain"), "businessName");
RequestBody bCountry = RequestBody.create(MediaType.parse("text/plain"), "businessCountry");
RequestBody bAboutUs = RequestBody.create(MediaType.parse("text/plain"), "businessAboutUs");
RequestBody bDetail = RequestBody.create(MediaType.parse("text/plain"), "businessDetail");
RequestBody bEmail = RequestBody.create(MediaType.parse("text/plain"), "businessEmail");
RequestBody bContact = RequestBody.create(MediaType.parse("text/plain"), "businessContact");
RequestBody bStep = RequestBody.create(MediaType.parse("text/plain"), "1");
I am not sending arraylists or image just to check the response, but still getting the same error.

Problem with working with Multipart form data Retrofit2

I know it is not wise to use multipart for simple text authentication. but I need to use it with api provided to me.
I tried all the methods possible.
It's working fine with postman
but not with retrofit 2
request type details
request type details
code used
tried
//RequestBody requestNameRq = RequestBody.create(MediaType.parse("text/plain"),serviceNameValue);
//RequestBody requestAmountRq = RequestBody.create(MediaType.parse("text/plain"),serviceAmountValue.toString());
/* Create Request Body */
//MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM)
// .addFormDataPart("service",serviceNameValue)
// .addFormDataPart("amount", String.valueOf(serviceAmountValue));
//RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
// .addFormDataPart("service",serviceNameValue)
// .addFormDataPart("amount",serviceAmountValue.toString()).build();
//MultipartBody.Part multipartRequestBody = MultipartBody.Part
// .createFormData("service",serviceNameValue)
// .createFormData("amount",serviceAmountValue.toString());
//MultipartBody multipartBody = builder.build();
Code for Apiservice
#POST("services")
Call<AddServiceResponse> addService(#Header("Authorization") String authToken,
//#Body MultipartBody body);
#Part("service") RequestBody service,
#Part("amount") RequestBody amount);
//#Part("service") String service,
//#Part("amount") String password);
//#Part("service") RequestBody service,
//#Part("amount") RequestBody amount);
}
Please try to add
#Multipart
before
#POST("services")
Modify your ApiService class
#Multipart
#POST("services")
Call<AddServiceResponse> addService(
#Header("Authorization") String authToken,
#Part("service") MultipartBody.Part service,
#Part("amount") MultipartBody.Part amount);
Then create MultipartBody
MultipartBody.Part serviceBody = MultipartBody.Part.createFormData("service", "Somethin2");
MultipartBody.Part amountBody = MultipartBody.Part.createFormData("amount", "2344");
Then call
apiService.addService(serviceBody, amountBody);

Multiple image uploading using multipart retrofit or volley

Hi Can any one Please help me out in uploading multiple images selected from gallery,
parameter is 'images' as array list
I have tried with this but no response can any one help me out..
This is my request body :
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
MultipartBody.Builder mRequestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
if (Imagepaths.size() > 0) {
for(String path:Imagepaths) {
File file = new File(path);
mediaType = path.endsWith("png") ?
MediaType.parse("image/png") : MediaType.parse("image/jpeg");
RequestBody imageBody = RequestBody.create(mediaType, file);
mRequestBody.addFormDataPart("images", file.getName(), imageBody);
}
}
RequestBody rb = mRequestBody.build();
This is the retrofit call :
#Multipart
#POST("upload_images/")
Call<ResponseBody> retrofitImageUpload(#Header("Authorization") String auth,
#Header("Content-Type") String contentType,
#Part("images") RequestBody req);

#Part in multipart sends the string parameters in double quote

Following API I called for Editing User Profile . I have to send user profile picture so I used multipart in API .
#Multipart
#POST(ApiURLs.EDIT_USER_PROFILE)
Call<EditProfileModel> EditUserProfile (#Part("user_id) String userId ,
#Part("user_name") String userName ,
#Part("language_id") String languageId ,
#Part("state_id") String stateId ,
#Part MultipartBody.Part
profilePicture);
When Service called the requested parameters would be like
"user_id" : ""23""
"user_name" : ""Keval Shukla""
"language_id": ""27""
"state_id" : "53""
how do i remove that double quote using MultiPart ?
It must be like -
#Multipart
#POST(ApiURLs.EDIT_USER_PROFILE)
Call<EditProfileModel> EditUserProfile (
#Part("user_id") RequestBody userId ,
#Part("user_name") RequestBody userName ,
#Part("language_id") RequestBody languageId ,
#Part("state_id") RequestBody stateId ,
#Part RequestBody profilePicture);
And, to create requestBody,
File file = new File(imageURI.getPath());
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file); // File requestBody
RequestBody userName = RequestBody.create(MediaType.parse("text/plain"), userNameSTRING); // String requestBody
You can send parameters other than file as RequestBody.
#Multipart
#POST(ApiURLs.EDIT_USER_PROFILE)
Call<EditProfileModel> EditUserProfile (#Part("user_id) RequestBody userId ,
#Part("user_name") RequestBody userName ,
#Part("language_id") RequestBody languageId ,
#Part("state_id") RequestBody stateId ,
#Part MultipartBody.Part profilePicture);
To Convert String to RequestBody:
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), userName); // Here userName is String
You are doing it wrong way, when you are using MultiPart as body type you have to specify body type of each request parameter.
For example, you are sending file(image,video etc.) and string parameters. So you need to specify all the parameters and convert it to specific body type.
You need to divide parameters into two parts,
1) MultipartBody - For media file
2) RequestBody - For other string or other data type parameters
e.g.
/*Create API Method*/
#Multipart
#POST("apiurl")
Call<Object> callMethodName(#Part("mobile_no") RequestBody mobile_no, /*String param */
#Part("password") RequestBody password, /*String param */
#Part MultipartBody.Part profile_img /*file param */);
I have define Parse type as multipart/form-data, you can define as according to your requirements,
public static final String MULTIPART_TYPE = "multipart/form-data";
Now create request parameters as below,
/* Adding String Params*/
RequestBody reqNumber = RequestBody.create(MediaType.parse(Constants.MULTIPART_TYPE), number.toString());
RequestBody reqPass = RequestBody.create(MediaType.parse(Constants.MULTIPART_TYPE), pass.toString());
/* Adding File*/
File file = new File(selectedImagePath);
RequestBody requestFile = RequestBody.create(MediaType.parse(Constants.MULTIPART_TYPE), file);
bodyFile = MultipartBody.Part.createFormData("profile_img", file.getName(), requestFile);
As last step, you need to pass request parameter to API call method as below, so it can identify parameters and send it to server.
/* Call API Method */
RestClient.getApiClient().callMethodName(reqNumber, reqPass, bodyFile);
Use RequestBody instead of String.
#Part("user_id") RequestBody user_id,
To call it
String userId= "123456";
RequestBody id =
RequestBody.create(
okhttp3.MultipartBody.FORM, userId);

Android Retrofit 2 multipart always giving error 400

I'm trying to send one image and somes string through retrofit, but it's not working, I'm always getting a 400. My app is already using webservices such as GET or POST without troubles, I assume that my probleme is with the upload...
I used that explanations and the github of retrofit.
My idea here is to create a new Dish and sed it to my server, so most of the data are comming from InputTextField and the photo is taken by the camera using an Intent
First my interface for uploading
#Multipart
#POST("japronto/api/chef/dish/new")
Call<Dish> upload(#Part("name") RequestBody name, #Part("description") RequestBody description,#Part("disponibility") RequestBody disp,#Part("max") RequestBody max,#Part("price") RequestBody price, #Part MultipartBody.Part file);
My function to upload
public void onOK(){
RequestBody name = RequestBody.create( MediaType.parse("multipart/form-data"), this.name.getText().toString());
RequestBody description =
RequestBody.create(
MediaType.parse("multipart/form-data"), this.description.getText().toString());
RequestBody disp =
RequestBody.create(
MediaType.parse("multipart/form-data"), Integer.toString(this.TorF));
RequestBody max =
RequestBody.create(
MediaType.parse("multipart/form-data"), this.max.getText().toString());
RequestBody price =
RequestBody.create(
MediaType.parse("multipart/form-data"), this.price.getText().toString());
File nImg = new File(folderImg, imgName);
RequestBody rqFile =
RequestBody.create(MediaType.parse("multipart/form-data"), nImg);
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", nImg.getName(), rqFile);
ApiService apiService = ApiManager.createService(ApiService.class, this.chef.getPseudo(), this.chef.getPassword());
Call<Dish> call = apiService.upload(name, description, disp, max, price, body);
call.enqueue(new Callback<Dish>() {
#Override
public void onResponse(Call<Dish> call, Response<Dish> response) {
Dish d = response.body();
Log.d(TAG, "onResponse: "+d.getName());
}
#Override
public void onFailure(Call<Dish> call, Throwable t) {
}
});
}
My view on the server
#app.route('/japronto/api/chef/dish/new', methods=['POST'])
def upload():
if request.method == 'POST':
if 'file' not in request.files:
print 'pbs'
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
print filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return {'name':filename}
return{'name':'erro'}
Any ideas?
Try this
#Multipart
#POST("japronto/api/chef/dish/new")
Call<Dish> upload(#Part("name") RequestBody name, #Part("description") RequestBody description,#Part("disponibility") RequestBody disp,#Part("max") RequestBody max,#Part("price") RequestBody price, #Part("ImageNameHere\"; filename=\"image.png\" ") RequestBody image);
File nImg = new File(folderImg, imgName);
RequestBody rqFile = RequestBody.create(MediaType.parse("image/png"), nImg);
check these links
Link 1 Link 2 Link 3

Categories

Resources