I want to send some data with retrofit including an image and three strings,
how should my WCF server side method signature be to handle these posted data if someone could help me?
The below code is my client side with retrofit(although im not sure it is well written).
#Multipart
#POST("PostBanderolDataJSON")
Call<MyResponse> PostData(#Part("banderolNr") RequestBody banderolNr, #Part("pharmacy") RequestBody pharmacy, #Part("place") RequestBody place, #Part("report_pic\"; filename=\"rp.png\" ") RequestBody file);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RetrofitApiInterface.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApiInterface api = retrofit.create(RetrofitApiInterface.class);
RequestBody reportImage = RequestBody.create(MediaType.parse("image/jpeg"), ImagePath);
RequestBody banderoNr = RequestBody.create(MediaType.parse("text/plain"), etBanderolNr.getText().toString());
RequestBody pharmacy = RequestBody.create(MediaType.parse("text/plain"), Pharmacy.getText().toString());
RequestBody place = RequestBody.create(MediaType.parse("text/plain"), Place.getText().toString());
Call<MyResponse> call = api.PostData(banderoNr,pharmacy,place,reportImage);
call.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (response.isSuccessful()) {
if (!response.body().error) {
Toast.makeText(getApplicationContext(), "Data Sent Successfully...", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Some error occurred...", Toast.LENGTH_LONG).show();
}
progress.dismiss();
}
else{
Toast.makeText(getApplicationContext(),"Something went wrong with the request to the server !",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
progress.dismiss();
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
Related
Link : https://mobileinterview.azurewebsites.net/api/products?PageIndex=1&PageSize=10
I am trying to call this API using retrofit in android using java but it does not return any response body it shows the response message is OK and the response code is 200, but still body is null.
Below is my code :
retrofit = new Retrofit.Builder()
.baseUrl(Constant.BaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
MyApiService services = retrofit.create(MyApiService.class);
Call<JSONArray> call = services.getAllData();
call.enqueue(new Callback<JSONArray>() {
#Override
public void onResponse(Call<JSONArray> call, Response<JSONArray> response) {
Log.i(TAG, "onResponse: "+response);
}
#Override
public void onFailure(Call<JSONArray> call, Throwable t) {
Log.i(TAG, "onFailure: "+t.getMessage());
}
});
Below is my interface class :
#GET("products?PageIndex=1&PageSize=10")
Call<JSONArray> getAllData();
your api data is xml based , you follow this topic for parsing the xml data , hopefully it will help your problem
https://codeleague.redquark.org/2018/08/parsing-xml-using-retrofit.html
I try many solutions but no once work for me.
I'm receiving images data in this way:
ArrayList<String> filePaths = data.getStringArrayListExtra(Pix.IMAGE_RESULTS);
and uploading images using multipart
MultipartBody requestBody = builder.build();
Call<Status_Response> call = taskMetServer.uploadMultiplePics(requestBody.parts());
call.enqueue(new Callback<Status_Response>() {
#Override
public void onResponse(Call<Status_Response> call, Response<Status_Response> response) {
if(response.isSuccessful()){
Status_Response status_response = response.body();
assert status_response != null;
String msg = status_response.getStatus();
Log.d("myMessage", "\n\nStatus: "+msg);
progressBar.setVisibility(View.GONE);
Toast.makeText(getContext(), "Success " + response.message()+response.code(), Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<Status_Response> call, Throwable t) {
progressBar.setVisibility(View.GONE);
Toast.makeText(getContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
my interface is:
#POST("test/store")
Call<Status_Response> uploadMultiplePics(
#Body List<MultipartBody.Part> images
);
but still receiving null in response instead of true of false:
2021-03-20 17:36:38.076 10582-10582/com.example.ourproductapp D/myMessage: [/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20210320-WA0082.jpeg]
2021-03-20 17:36:38.732 10582-10582/com.example.ourproductapp D/myMessage: Status: null
Thanks in advance
check your backend service, your server is getting file or not.
or you can use https://github.com/gotev/android-upload-service library
i'm using retrofit2 library for post data to server, I need to upload a file or photo with POST request and get it's response. So i have two ways:
Encoding the file to base64 and sending it as a text in post body.
Using Multi part request and sending the file directly .
And i tried them, but in both ways, i have same problem:
when I send small files (for example under 500 bytes),I get successful result.
But the problem occurs when i send a large file. I get nothing until the timeout finishes, in AVD I get successful response (Also in Postman), but in real devices (HTC with android 5.1 & Samsung S6 with Android 7.0) the below error occurs:
java.io.IOException: unexpected end of stream on Connection{myIp:port, proxy=DIRECT# hostAddress=/myIp:port cipherSuite=none protocol=http/1.1
Call Method:
#Multipart
#POST("uploaddata")
Call<ResponseBody> uploaddate(#Part("file") RequestBody filePart, #Part("token") RequestBody token,
#Part("type") RequestBody type, #Part("name")RequestBody name);
Main method:
public void uploadImage(String type, File file, String name, String token, final DataInterface listener) {
RequestBody filePart = RequestBody.create(MediaType.parse("image/*"), file);
RequestBody tokenPart = RequestBody.create(MediaType.parse("text/plain"), token);
RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"), name);
RequestBody typePart = RequestBody.create(MediaType.parse("text/plain"), type);
Call<ResponseBody> uploadData = apiInterface.uploaddate(filePart, tokenPart, typePart, namePart);
uploadData.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
listener.onResponseListener(response.body());
} else {
Log.e(TAG, "uploadData -----> response.isSuccessful == false");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "uploadData onFailure -----> " + t);
}
});
}
Can you post the log output of your error
Did it return anything like a large binary data ??
Try this:
#Multipart
#POST("uploaddata")
Call<ResponseBody> uploaddate(#Part MultiPart.Body filePart,
#Part("token") RequestBody token,
#Part("type") RequestBody type,
#Part("name")RequestBody name);
Main method:
public void uploadImage(String type, File file, String name, String token,
final DataInterface listener) {
RequestBody filePart = RequestBody.create(MediaType.parse("image/*"), file);
MultiPartBody.Part body = MultiPartBody.Part.createFormData("filePart",file.getName(),filePart);
RequestBody tokenPart = RequestBody.create(MediaType.parse("text/plain"), token);
RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"), name);
RequestBody typePart = RequestBody.create(MediaType.parse("text/plain"), type);
Call<ResponseBody> uploadData = apiInterface.uploaddate(body, tokenPart, typePart, namePart);
uploadData.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
listener.onResponseListener(response.body());
} else {
Log.e(TAG, "uploadData -----> response.isSuccessful == false");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "uploadData onFailure -----> " + t);
}
});
}
I am using retrofit library with post request, but i did not found data. Give "Internal server error" message.
API_1 : http://www.fabgrad.com/dummy_api_1/
type : POST
data : { us_id:23 }
interface -
public interface FirstApi {
public static String URl = "http://www.fabgrad.com/";
#FormUrlEncoded
#POST("dummy_api_1")
Call<Titles> getData(#Field("us_id") String id);
}
Using retrofi in main activity -
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(FirstApi.URl)
.addConverterFactory(GsonConverterFactory.create())
.build();
FirstApi categoryMenuApi = retrofit.create(FirstApi.class);
String s="23";
Call<Titles> categoryMenuCall = categoryMenuApi.getData(s);
categoryMenuCall.enqueue(new Callback<Titles>() {
#Override
public void onResponse(Call<Titles> call, Response<Titles> response) {
Titles list = response.body();
}
#Override
public void onFailure(Call<Titles> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
I am new in retrofit So please help
You only have to add / at the end of your endpoint #POST("dummy_api_1")
Just like:
#POST("dummy_api_1/")
I am trying to send image files from my android app to a back end server. On Postman, images are sent and response code:200 is received.
However, trying to send images from my android app using retrofit, I keep receiving response code:500 Internal Server Error. Here is my code:
public interface RetrofitInterface {
#Multipart
#POST("uploads/addImage")
Call<ResponseBody> uploadImage(#Part MultipartBody.Part image);
}
The NetworkClient
public class NetworkClient {
private static Retrofit retrofit;
public static Retrofit getRetrofit(){
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS).build();
if(retrofit == null){
String BASE_URL = "https://addimage.herokuapp.com/";
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).
addConverterFactory(GsonConverterFactory.create()).client(okHttpClient).build();
}
return retrofit;
}
}
And then the call
private void uploadImage(Uri imageUri){
File file = new File(imageUri.toString());
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);
Retrofit retrofit = NetworkClient.getRetrofit();
RetrofitInterface retrofitInterface = retrofit.create(RetrofitInterface.class);
Call<ResponseBody> call = retrofitInterface.uploadImage(body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
Log.d("UploadImage", "Yeepee!!! = "+response.message());
}else Log.d("UploadImage", "Response failure = "+response.message());
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
// "Connection Timeout";
Log.e("UploadImage", "Connection Timeout");
} else if (t instanceof IOException) {
// "Timeout";
Log.e("UploadImage", "Timeout");
} else {
//Call was cancelled by user
if(call.isCanceled()) {
Log.e("UploadImage", "Call was cancelled forcefully");
} else {
//Generic error handling
Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
}
}
}
});
}
I am not sure if it's a server error since images upload successfully from Postman. I am very confused and I am not sure what I am doing wrong.
According to your Postmen screen shot there is no key for image file can you try like below
remove this line
MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);
And add this one
MultipartBody.Part body = MultipartBody.Part.createFormData("", "image.jpg", requestBody);
Generally 500 Internal Server error means there is something wrong in the server, but if the Postman is giving 200 that means the server part is OK, there's something wrong in your code.
try changing this line
File file = new File(imageUri.toString());
to this
File file = new File(imageUri.path);
And also make sure that the key name you used is same as the response key name
Thank you all for your responses. I have been able to resolve and it turned out to be a conflict between my request body and what the server was expecting.
For my case, I was sending a different mime-type(a .jpg), where the server developer made the server look for .jpeg and .png.
This was how I got to see the error and resolve the conflict.
Call<ResponseBody> call = retrofitInterface.uploadImage(body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
Log.d("UploadImage", "Yeepee!!! = "+response.message());
}else {
Log.d("UploadImage", "Response failure = "+response.message());
try {
Log.d("UploadImage", "Response failure = "+response.errorBody().string());
} catch (IOException e) {
Log.d("UploadImage", "IOException = "+e.getMessage());
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
// "Connection Timeout";
Log.e("UploadImage", "Connection Timeout");
} else if (t instanceof IOException) {
// "Timeout";
Log.e("UploadImage", "Timeout");
} else {
//Call was cancelled by user
if(call.isCanceled()) {
Log.e("UploadImage", "Call was cancelled forcefully");
} else {
//Generic error handling
Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
}
}
}
});
The response.errorBody().string() got the error message from the server and I was able to resolve the conflict.