I am building a Laravel-based API. In the project, I want to upload image using post method to the API server
the image file is uploading on localhost database but when I try to upload the image on online server which is namecheap there image error code is 405.
I wasted 2 days but I don't now what is the error.
Please anyone can help me.
Thanks in advance
Here is android code
#Multipart
#POST("update-client")
Call<CustomerModel> update_user(#Part("id") RequestBody id,
#Part("name") RequestBody name, #Part("address") RequestBody address,
#Part("user_op_phone") RequestBody city,
#Part MultipartBody.Part file,
#Part("avatar") RequestBody image);
public void update_user_info(String name,String address,String no){
progressDialog.show();
RequestBody requestFile = null;
MultipartBody.Part body = null;
if(file!=null && file.length()>0) {
requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
body =
MultipartBody.Part.createFormData("avatar", file.getName(), requestFile);
}
RequestBody p_id = RequestBody.create(MediaType.parse("text/plain"),appSessionManager.getUserId());
RequestBody p_name = RequestBody.create(MediaType.parse("text/plain"),name);
RequestBody p_address = RequestBody.create(MediaType.parse("text/plain"),address);
RequestBody p_no = RequestBody.create(MediaType.parse("text/plain"),no);
Call<CustomerModel> call1 = apiPHP.update_user(body,requestFile);
call1.enqueue(new Callback<CustomerModel>() {
#Override
public void onResponse(Call<CustomerModel> call, Response<CustomerModel> response) {
progressDialog.dismiss();
// VendorModel user1 = response.body();
if(response.errorBody()==null){
// if(response.code()==201) {
Toast.makeText(getApplicationContext(), response.body().message, Toast.LENGTH_LONG).show();
// }
}
}
#Override
public void onFailure(Call<CustomerModel> call, Throwable t) {
Toast.makeText(getApplicationContext(),t.getMessage() , Toast.LENGTH_SHORT).show();
call.cancel();
}
});
}
Laravel Api routes is
Route::post("update-client", "Client\ClientController#updateClient");
Related
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...
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());
Hello guys here is my sample code
#FormUrlEncoded
#Multipart
#POST("registration.php")
Call<Signup> getSignupResponse(#Field("email") String email,
#Field("lname") String lname,
#Field("fname") String fname,
#Field("password") String password,
#Part("filename") File file);
Issue is when i am trying to add File Parameter as a Part its throwing me a error other wise if i use only #Field it works great but not working after i add #Part in it
- is there a no way to use #Field and #part together in Retrofit??
- If yes than tell a reason, If no tell me a proper way
I will appreciate your answer and thank you in advance
Note : Tell me a suggestions in comments before you vote.
You cannot use both #FormUrlEncoded and #Multipart on a single method.
An HTTP request can only have one Content-Type and both of those are
content types.
#FormUrlEncoded (for android) | application/x-www-form-urlencoded(for web)
#Multipart (for android) | multipart/form-data(for web)
use like this .....
#Multipart
#POST("photos/upload")
Call<Result> upload(#Part("Token") RequestBody token, #Part("Photo_Type") RequestBody type, #Part MultipartBody.Part file );
and in call like this .....
String token="your string";
File file = new File(path);
RequestBody tokenRequest = RequestBody.create(MediaType.parse("text/plain"), token);
RequestBody type = RequestBody.create(MediaType.parse("text/plain"), true + "");
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
Call<Result> call = qikGrubApi.upload(tokenRequest, type, filePart);
call.enqueue(new Callback<Result>() {
#Override
public void onResponse(Call<Result> call, Response<Result> response) {
progress.dismiss();
if (response.isSuccessful()) {
if (response.body().getSuccess()) {
nextPage(response.body().getMessage());
} else
Toast.makeText(UploadActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(UploadActivity.this, "Sorry for inconvince server is down", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Result> call, Throwable t) {
progress.dismiss();
Toast.makeText(UploadActivity.this, "Check your Internet connection", Toast.LENGTH_SHORT).show();
}
});
}
Note:- Use above example for your File POST and let me know , if you stuck anywhere.
For more Detail info click this
EDIT:-
For your case use like this .....
#Multipart
#POST("registration.php")
Call<Signup> getSignupResponse(#Part("email") RequestBody email,
#Part("lname") RequestBody lname,
#Part("fname") RequestBody fname,
#Part("password") RequestBody password,
#Part MultipartBody.Part filename);
and use retrofit call like this .....
File file = new File(path);
RequestBody emailRequest = RequestBody.create(MediaType.parse("text/plain"), email);
RequestBody lnameRequest = RequestBody.create(MediaType.parse("text/plain"), lname);
RequestBody fnameRequest = RequestBody.create(MediaType.parse("text/plain"), fname);
RequestBody passwordRequest = RequestBody.create(MediaType.parse("text/plain"), password);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
Call<Signup> call = qikGrubApi.upload(emailRequest, lnameRequest ,fnameRequest , passwordRequest, filePart);
call.enqueue(new Callback<Signup>() {
#Override
public void onResponse(Call<Signup> call, Response<Signup> response) {
progress.dismiss();
if (response.isSuccessful()) {
if (response.body().getSuccess()) {
nextPage(response.body().getMessage());
} else
Toast.makeText(UploadActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(UploadActivity.this, "Sorry for inconvince server is down", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Signup> call, Throwable t) {
progress.dismiss();
Toast.makeText(UploadActivity.this, "Check your Internet connection", Toast.LENGTH_SHORT).show();
}
});
}
Example
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.
I'm sending object in request body, something like that :
{
"title":"test",
"description":"test",
"images":[]
}
#POST("create-data")
Call<JsonObject> publishData(#Body MyObject object);
and it's work fine without the images. From the docs I can find how to upload file to server using MultipartBody.Part, my questions is :
How can I upload multiple images at the same time?
Is it possible to send the images inside the object, or I need to send it separately and how ?
thank you very much.
request success just now with server
I reference the article:
https://futurestud.io/blog/retrofit-2-how-to-upload-files-to-server
#Multipart
#POST("uploadHeadPic")
Call<UploadHeadPicResponseModel> uploadHeadPic(#Part MultipartBody.Part file, #Part("json") RequestBody json);
public void doUploadHeadPic(#NonNull String filePath) {
if (!MNetworkUtil.isNetworkAvailable()) {
MToastUtil.show("网络不能连接");
return;
}
File file = new File(filePath);
String json = new Gson().toJson(new UploadHeadPicRequestModel());
if (!file.exists()) {
MToastUtil.show("文件不存在");
return;
}
progressDialog.show();
avatarSimpleDraweeView.setEnabled(false);
MApiManager.getService().uploadHeadPic(
MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file)),
RequestBody.create(MediaType.parse("multipart/form-data"), json))
.enqueue(new OnRetrofitCallbackListener<UploadHeadPicResponseModel>(mActivity) {
#Override
public void onSuccess(UploadHeadPicResponseModel responseModel) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
if (responseModel != null) {
String serverAvatarUrl = responseModel.data.headPicPath;
if (!TextUtils.isEmpty(serverAvatarUrl)) {
UserModel userModel = MUserManager.getInstance().getUser();
if (userModel != null) {
userModel.setAvatarUrl(serverAvatarUrl);
MUserManager.getInstance().updateOrInsertUserInfo(userModel);
MToastUtil.show("上传头像成功");
}
}
}
}
#Override
public void onFailure(int status, String failureMsg) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
MToastUtil.show((TextUtils.isEmpty(failureMsg) ? "上传失败" : failureMsg) + " : " + status);
}
});
}
update for multi files
may be this could help , I did not try
#Multipart
#POST("uploadHeadPic")
Call<UploadHeadPicResponseModel> uploadHeadPic(#Part MultipartBody.Part file0, #Part MultipartBody.Part file1, #Part("json") RequestBody json);
public void doUploadHeadPic(#NonNull String filePath) {
MApiManager.getService().uploadHeadPic(
MultipartBody.Part.createFormData("file0", file0.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file0)),
MultipartBody.Part.createFormData("file1", file1.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file1)),
RequestBody.create(MediaType.parse("multipart/form-data"), json))
.enqueue(new OnRetrofitCallbackListener<UploadHeadPicResponseModel>(mActivity) {
#Override
public void onSuccess(UploadHeadPicResponseModel responseModel) {
}
#Override
public void onFailure(int status, String failureMsg) {
}
});
}
In my case (uploading to server built with Spring) I needed to change MediaType for RequestBody:
RequestBody.create(MediaType.parse("application/json"), json)
RequestBody.create(MediaType.parse("image/jpg"), file)