Retrofit 2 multipart file upload with different file names - android

This is my code. It properly works. But I want to upload other image types like png, jpeg ,etc. Therefore I want to change filename=\"file1.jpeg"
Also I want to send different number of files at the same time.
Please help me to resolve this. Thank you.
public interface FileUploadService {
#Multipart
#POST("upload")
Call<ResponseBody> upload(#Part("description") RequestBody description,#Part("file1\"; filename=\"file1.jpeg") RequestBody file1);
}
private void uploadFile() {
FileUploadService service =
ServiceGenerator.createService(FileUploadService.class);
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), new File("/path/to/mypic.jpeg"));
String descriptionString = "hello, this is description speaking";
RequestBody description =
RequestBody.create(
MediaType.parse("multipart/form-data"), descriptionString);
Call<ResponseBody> call = service.upload(description, body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
Log.v("Upload", "success");
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
}

Try this one:
#POST("upload")
fun upload(#BODY parts: MultipartBody): Call<ResponseBody>
and the client side would look like this:
val parts = MultipartBody.Builder()
.addFormDataPart(name = "name",filename = "yourDynamicFileName", RequestBody.create(...))
.build()
// don't forget to name an extension of your file
api.upload(parts).execute()

Related

How to upload file via Retrofit

I am trying to upload files from android device to the server using retrofit.
But every time, it results with no in the console.
FilesApi.java:
public interface FilesApi {
#Multipart
#POST("file")
Call<String> storeFile(#Part MultipartBody.Part file);
}
In MainActivity.java:
private void uploadFile(){
RequestBody requestFile= RequestBody.create(MediaType.parse("multipart/form-data"),file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", file.getName(), requestFile);
//RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),file);
FilesApi api = RetrofitService.createService(FilesApi.class);
api.storeFile(body).enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.d(TAG, "onResponse: "+response.body());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d(TAG, "onFailure: "+t);
}
});
}
PHP code:
<?php
if(isset($_FILES['file']))
{
echo "YESS";
}
else
{
echo "no";
}
?>
The Filename should be the same on the Retrofit Parameter as well on the Server Key.
Please refer this link for complete guidance.
https://www.simplifiedcoding.net/retrofit-upload-file-tutorial/

Upload files using retrofit2 - file was being uploaded but on "onFailure" response

I need to upload an image as a file, already tried different solutions from the stack but I still stuck. Anyone can explain to me what I am doing wrong?
UPLOAD FUNCTION
private void EnviarFotos(){
iGeoPBService geoPBService = GeoPBService.getInstance().usarServico();
List<Foto> listaFotos = bancoDadosController.syncFotos();
for (final Foto foto : listaFotos){
String numObra = foto.getNumeroObra();
String idAcomp = foto.getIdAcompanhamento();
String idMedicao = foto.getIdMedicao();
String imagem = foto.getImagem();
final File file = FileFoto(imagem);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"),file);
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file",foto.getNomeFoto(),requestFile);
if (idAcomp.equals("N/A")){
Call<String> envioMed = geoPBService.uploadFotoMedicao(idJurisdicionado,numObra,idMedicao,multipartBody);
envioMed.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()){
bancoDadosController.atualizaStatusSyncFoto(foto.getNomeFoto());
AttInfos();
Log.d("TESTE","FOTO ENVIADA COM SUCESSO!!!");
file.delete();
}else {
Log.d("TESTE","msg :"+ response.message());
Log.d("TESTE","errorBody :"+ response.errorBody().toString());
Toast.makeText(getBaseContext(),response.message(),Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("TESTE","DEU MERDA!!!");
Log.d("TESTE","throw :"+ t.getMessage());
Log.d("TESTE","cause :"+ t.getCause());
Log.d("TESTE","lmsg :"+ t.getLocalizedMessage());
Log.d("TESTE","Stack :"+ t.getStackTrace().toString());
Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}else {
Call<String> envioAcomp = geoPBService.uploadFotoAcompanhamento(idJurisdicionado,numObra,idAcomp,multipartBody);
envioAcomp.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
AttInfos();
Log.d("TESTE","FOTO ENVIADA COM SUCESSO!!!");
file.delete();
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("TESTE","DEU MERDA!!!");
Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
}
}
INTERFACE
public interface iGeoPBService {
#Multipart
#POST("obras/uploadFotoMedicao/{jurisdicionado}/{numObra}/{idMedicao}")
Call<String> uploadFotoMedicao(#Path("jurisdicionado") String idJurisdicionado,#Path("numObra")String numObra,#Path("idMedicao") String idMedicao, #Part MultipartBody.Part file);
#Multipart
#POST("obras/uploadFotoAcompanhamento/{jurisdicionado}/{numObra}/{idAcompanhamento}")
Call<String> uploadFotoAcompanhamento(#Path("jurisdicionado") String idJurisdicionado, #Path("numObra")String numObra, #Path("idAcompanhamento") String idAcompanhamento, #Part MultipartBody.Part file);
}
My code already has some changes based on other answers a similar question about upload files with retrofit2 but after executing my code always fall on "onFailure"
Logcat show this:
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
throw :Expected value at line 1 column 1 path $
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
cause :null
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
localized msg :Expected value at line 1 column 1 path $
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
Stacktrace :[Ljava.lang.StackTraceElement;#b4b765b
My file was being uploaded to the server but on retrofit "onFailure" response method
What I'm doing wrong? Actually, the problem can be on the server side?
[EDIT]
I changed some things on my code and now I'm getting the "onResponse" correctly.
SERVICE CLASS
private void buildRetrofit(String baseUrl) {
*OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
clientBuilder.addInterceptor(logging);
clientBuilder.retryOnConnectionFailure(false);
clientBuilder.followRedirects(true);
OkHttpClient client = clientBuilder.retryOnConnectionFailure(true).build();*
*Gson gson = new GsonBuilder()
.setLenient()
.create();*
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
*.client(client)*
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
this.requestsGeo = retrofit.create(iGeoPBService.class);
}
INTERFACE
#Multipart
#POST("obras/uploadFotoMedicao/{jurisdicionado}/{numObra}/{idMedicao}")
Call<ResponseBody> uploadFotoMedicao(#Path("jurisdicionado") String idJurisdicionado, #Path("numObra")String numObra, #Path("idMedicao") String idMedicao, #Part MultipartBody.Part file, #Part("name") RequestBody name);
#Multipart
#POST("obras/uploadFotoAcompanhamento/{jurisdicionado}/{numObra}/{idAcompanhamento}")
Call<ResponseBody> uploadFotoAcompanhamento(#Path("jurisdicionado") String idJurisdicionado, #Path("numObra")String numObra, #Path("idAcompanhamento") String idAcompanhamento,#Part MultipartBody.Part body,#Part("name") RequestBody name);
Just change your RequestBody to this:
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
Your MediaType sent were wrong...

android file upload with retrofit to asp.net web api

I'm trying to make a file upload with a picture and an string parameter, the file gets upload successfuly, but the string paremeter is always null. Could someone else help me please? Thanks in advance!
//Retrofit Interface
#Multipart
#POST("account/imageupload")
Call<ResponseBody> uploadProfilePicture(#Part MultipartBody.Part file,
#Part("userid") RequestBody userid);
//Activity
ApiClient apiClient = new ApiClient(token.getAccessToken(), "multipart/form-data");
ApiInterface apiService = apiClient.getClient().create(ApiInterface.class);
File file = new File(selectedImagePath);
RequestBody reqFile = RequestBody.create(MediaType.parse(getContentResolver().getType(selectedImageUri)), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), reqFile);
RequestBody user = RequestBody.create(MultipartBody.FORM, token.getUserId());
Call<ResponseBody> call = apiService.uploadProfilePicture(body, user);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
int statusCode = response.code();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
String message = t.getMessage();
}
});
//Web API (C# web api)
[Route("imageupload")]
[HttpPost]
public async Task<IHttpActionResult> UploadProfilePicture([FromBody]
Models.ProfilePhotoUpload photo)
{
WriteImage(photo.file);
return Ok();
}
//Api Controller Model
public class ProfilePhotoUpload
{
string userid { get; set; }
public HttpFile file { get; set; }
}
The problem is that the file gets uploaded correctly, but the userid parameter is always null.
You are creating incorrect RequestBody for text
Try this:
RequestBody user = RequestBody.create(MediaType.parse("text/plain"), token.getUserId());

Retrofit2 uploading an image

I am trying to get my Retrofit2 to upload an image to my Flask server, I am not sure why it is not sending the parameter "file" when sending the request.
APIInteface.java
#Multipart
#PUT("api/user/update/")
Call<ResponseBody> UpdateUser(#QueryMap Map<String,String> options,
#Part MultipartBody.Part image, #Part("file") RequestBody file);
MainActivity:
File file = new File(filePath);
Log.d(TAG,"Calling update function");
update(file);
}
}
public void update(File file) {
Log.d(TAG,"I got called, yey!");
ApiInterface apiService = ApiClient.GetAuthClient(token).create(ApiInterface.class);
RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), reqFile);
RequestBody name = RequestBody.create(MediaType.parse("multipart/form-data"), "upload_test");
data.put("uname",username.getText().toString());
data.put("fname",firstname.getText().toString());
data.put("lname",lastname.getText().toString());
data.put("address",address.getText().toString());
data.put("password",password.getText().toString());
data.put("preferance1",String.valueOf(spinner1.getSelectedItem()));
data.put("preferance2",String.valueOf(spinner2.getSelectedItem()));
data.put("preferance3",String.valueOf(spinner3.getSelectedItem()));
Call<ResponseBody> call = apiService.UpdateUser(data,body,name);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
}

How to upload image using Retrofit2 and save it on NodeJS server?

I have android app that posts image to NodeJS server using Retrofit2.
Here is my Android/Java code:
public interface ApiInterface {
String ENDPOINT = "http://192.168.0.11:1337/";
#Multipart
#POST("users/avatar")
Call<Avatar> postAvatar(#Part("description") RequestBody description, #Part("image") MultipartBody.Part file);
public static final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
private void uploadAvatar(final String userid){
File file = new File("/storage/emulated/0/Android/data/com.bcg.loginexample/files/pic.jpg");
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body =MultipartBody.Part.createFormData("image", file.getName(), requestFile);
String descriptionString = "hello, this is description speaking";
RequestBody description =RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString);
ApiInterface mApiService = ApiInterface.retrofit.create(ApiInterface.class);
Call<Avatar> mService= mApiService.postAvatar(description, body );
mService.enqueue(new Callback<Avatar>() {
#Override
public void onResponse(Call<Avatar> call, Response<Avatar> response) {
Avatar avatar = response.body();
String returnedResponse = avatar.avatar_url;
Toast.makeText(LoginActivity.this, "Returned " + returnedResponse, Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(Call<Avatar> call, Throwable t) {
call.cancel();
Toast.makeText(LoginActivity.this, "Please check your network connection", Toast.LENGTH_LONG).show();
}
});
}
And NodeJS
app.post('/users/avatar', type,
function (req, res) {
var filePath = __dirname + '/uploads/avatar.jpg';
fs.appendFile(filePath, req.body.image, function () {
res.end('file uploaded');
});
});
This is all I see in body object at NodeJS side.
"{"headers":{"namesAndValues":["Content-Disposition","form-data; name=\"image\"; filename=\"pic.jpg\""]}}"
Don't understand where is the image here and how to save it ??
You need some extra middleware to handle multipart/form-data (upload of binary data). You can take a look at the multer module for example.

Categories

Resources