Я пытаюсь опубликовать изображения на сервере. Вот мои имена переменных php на стороне сервера, предоставленные мне скриптором:
$value1 = $_POST["value1"]; // string value
$value2 = $_POST["value2"]; // string value
$img_1 = $_FILES["fileToUpload1"]["name"]; // image file
$img_2 = $_FILES["fileToUpload2"]["name"]; // image file
и вот мой код для публикации значений —
RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), path.toString());
RequestBody fileBody1 = RequestBody.create(MediaType.parse("image/png"), path.toString());
Call<uploadResponseModel> call = adapter.uploadValues("test1","test2",fileBody1,fileBody);
call.enqueue(new Callback<uploadResponseModel>() {
@Override
public void onResponse(Response<uploadResponseModel> response, Retrofit retrofit) {
Log.i("TAG", "retro onResponse :" + response.body().getResponse().getStatus());
}
@Override
public void onFailure(Throwable t) {
Log.i("TAG", "retro onFailure :" + t.getCause());
}
});
класс адаптера:
public interface RetrofitAdapter {
@Multipart
@POST("/TestApp/img_upload.php")
Call<uploadResponseModel> uploadValues(@Part("value1")String value1,@Part("value2")String value2,@Part("fileToUpload1") RequestBody file1,@Part("fileToUpload2") RequestBody file2);
}
Оба строковых значения публикуются на сервере, но не изображения. Пожалуйста, исправьте меня, если я где-то ошибаюсь при публикации файлов изображений. Я новичок в модернизации.
В соответствии с вашим вопросом, переменная, которую ожидает ваш сервер в виде двух изображений (файлов) fileToUpload1
а также fileToUpload2
, Причина, по которой изображения не загружаются из-за синтаксиса, который вы указали в RetrofitAdapter
,
Вам придется изменить свой RetrofitAdapter
чтобы:
public interface RetrofitAdapter {
@Multipart
@POST("/TestApp/img_upload.php")
Call<uploadResponseModel> uploadValues(@Part("value1")String value1,@Part("value2")String value2,@Part("fileToUpload1\"; filename=\"image\" ") RequestBody file1,@Part("fileToUpload2\"; filename=\"image\" ") RequestBody file2);
}
@Part («fileToUpload1 \»; filename = \ «image \» «) RequestBody file1
Сервер ожидает файл с именем переменной fileToUpload1
а также fileToUpload2
который должен быть размещен вместе с именем файла в вышеуказанном формате. Вы можете также найти решение здесь кликните сюда
Сделай это и у тебя все получится 🙂
Это мой сервисный метод для загрузки нескольких файлов:
@Multipart
@POST("http://....")
Call<UploadResponse> uploadPicture(@PartMap Map<String,RequestBody> pic1, @PartMap Map<String, RequestBody> pic2);
И как это назвать:
public void uploadPicture(File pic1, File pic2) {
Map<String, RequestBody> pic1Map = new HashMap<>();
Map<String, RequestBody> pic2Map = new HashMap<>();
RequestBody rb1 = RequestBody.create(MediaType.parse("image/*"), pic1);
RequestBody rb2 = RequestBody.create(MediaType.parse("image/*"), pic2);
pic1Map.put("file\"; filename=\"" + pic1.getName(), rb1);
pic2Map.put("file\"; filename=\"" + pic2.getName(), rb2);
Call<UploadResponse> call = apiClient.getAPIService().uploadPicture(pic1Map, pic2Map);
call.enqueue...
}
Некоторые бэкэнды требуют параметр заголовка файла, поэтому я использую @PartMap
сюда. Многокомпонентный компоновщик OkHttp не устанавливает его.
Вместо RequestBody просто используйте RequestBody. Исправить метод uploadValues
в интерфейсе Retrofit:
public interface RetrofitAdapter {
@Multipart
@POST("/TestApp/img_upload.php")
Call<uploadResponseModel> uploadValues(@Part("value1")String value1,@Part("value2")String value2,@Part("fileToUpload1") TypedFile file1,@Part("fileToUpload2") TypedFile file2);
}
И исправим ваш запрос сервиса:
TypedFile file1 = new TypedFile("application/octet-stream", new File(path1));
TypedFile file2 = new TypedFile("application/octet-stream", new File(path2));
Call<uploadResponseModel> call = adapter.uploadValues("test1","test2",file1,file2);
call.enqueue(new Callback<uploadResponseModel>() {
@Override
public void onResponse(Response<uploadResponseModel> response, Retrofit retrofit) {
Log.i("TAG", "retro onResponse :" + response.body().getResponse().getStatus());
}
@Override
public void onFailure(Throwable t) {
Log.i("TAG", "retro onFailure :" + t.getCause());
}
});
Вы звоните неправильно create
метод RequestBody
. Вы передаете строку, которая использует строку в качестве содержимого. Вы должны пройти File
, Не понятно какой тип твой path
переменная есть. Если это уже File
, используй это. В противном случае создайте файл и передайте его create
—
File image = new File(path.toString());
RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), image);
сделать то же самое для fileBody1
,
Я думаю, что метод для отправки обычной строки и файла отличается.
ты должен использовать
@Part("file\"; filename=\"fileToUpload1.png\"") RequestBody file1
вместо
@Part("fileToUpload1") RequestBody file1
или если вы хотите быть конкретным
@Part("image\"; filename=\"fileToUpload1.png\"") RequestBody file1
Есть некоторые проблемы с многочастной загрузкой файлов с модификацией @Multipart
тег.
Решил проблему с помощью @POST
тег с настраиваемым составным компонентом в теле запроса.
@POST ("userwebservices/app_upload_pic")
Call<APIRespone> uploadUserImages ( @Body RequestBody file );
Код для многокомпонентной загрузки, передавая путь к файлу изображения из приложения для Android.
File file = new File(filePath);
MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data;name=\"uploaded_file\";filename=\"" + filePath + "\""),
RequestBody.create(MEDIA_TYPE_IMAGE, file))
.build();
Вот uploaded_file
проверочная строка в сценарии PHP