Я пытаюсь сделать HTTP POST на сервер с помощью Retrofit 2.0
MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain");
MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG,90,byteArrayOutputStream);
profilePictureByte = byteArrayOutputStream.toByteArray();
Call<APIResults> call = ServiceAPI.updateProfile(
RequestBody.create(MEDIA_TYPE_TEXT, emailString),
RequestBody.create(MEDIA_TYPE_IMAGE, profilePictureByte));
call.enqueue();
Сервер возвращает ошибку о том, что файл недействителен.
Это странно, потому что я пытался загрузить тот же файл в том же формате на iOS (с использованием другой библиотеки), но он успешно загружен.
Мне интересно, как правильно загрузить изображение с помощью Retrofit 2.0 ?
Должен ли я сохранить его на диск перед загрузкой?
PS: я использовал модификацию для другого запроса Multipart, который не включает изображение, и они успешно завершены. Проблема в том, когда я пытаюсь включить байт в тело.
android
retrofit
androidhttpclient
retrofit2
JayVDiyk
источник
источник
Ответы:
Я подчеркиваю решение в 1.9 и 2.0, так как это полезно для некоторых
Во-
1.9
первых, я думаю, что лучшее решение - это сохранить файл на диск и использовать его как типизированный файл, например:RetroFit 1.9
(Я не знаю о вашей реализации на стороне сервера) есть метод интерфейса API, подобный этому
И используйте это как
Для RetroFit 2 используйте следующий метод
RetroFit 2.0 (это был обходной путь для проблемы в RetroFit 2, которая исправлена, правильный метод см. В ответе jimmy0251 )
API интерфейс:
Используйте это как:
источник
@Multipart @POST("/api/Accounts/editaccount") Call<User> editUser(@PartMap Map<String, RequestBody> params);
И, когда у вас есть файл:Map<String, RequestBody> map = new HashMap<>(); RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpg"), file); map.put("file\"; filename=\"" + file.getName(), fileBody);
MultiPartBody.Part
Существует правильный способ загрузки файла с его именем с помощью Retrofit 2 без какого-либо взлома :
Определить интерфейс API:
Загрузить файл так:
Это демонстрирует только загрузку файла, вы также можете добавить другие параметры в том же методе с
@Part
аннотацией.источник
MultipartBody.Part
аргументов в одном API.@Part("images[]") List<MultipartBody.Part> images
но это дает ошибку, что@Part parameters using the MultipartBody.Part must not include a part name
@Body MultipartBody multipartBody
иMultipartBody.Builder
для отправки коллекции изображений.Я использовал Retrofit 2.0 для своих зарегистрированных пользователей, отправлял multipart / form файл изображения и текст из учетной записи
В моем RegisterActivity используйте AsyncTask
А в моем классе Register.java есть где использовать Retrofit с синхронным вызовом
В интерфейсе RegisterService
Для анализа утилит или ответа InputStream
источник
Обновить код для загрузки файла изображения в Retrofit2.0
Изменить
MediaType.parse("image/*")
наMediaType.parse("image/jpeg")
источник
@Multipart
то@Part
аннотации должны предоставить имя или MultipartBody.Part типа параметра.@Part("profile_pic\"; filename=\"pp.png "
Добавление к ответу, данному @insomniac . Вы можете создать
Map
параметр дляRequestBody
включения изображения.Код для интерфейса
Код для Java-класса
источник
Так что это очень простой способ достичь своей цели. Вы должны следовать ниже шаг:
1. Первый шаг
Вам нужно сделать весь звонок как
@Multipart request
.item
иimage number
это просто тело строки, которое обернутоRequestBody
. Мы используем то,MultipartBody.Part class
что позволяет нам отправлять фактическое имя файла помимо данных двоичного файла с запросом2. Второй шаг
Теперь у вас есть
image path
и вам нужно конвертировать вfile
.Now конвертироватьfile
вRequestBody
использование методаRequestBody.create(MediaType.parse("multipart/form-data"), file)
. Теперь вам нужно конвертироватьRequestBody requestFile
вMultipartBody.Part
метод использованиеMultipartBody.Part.createFormData("Image", file.getName(), requestBody);
.ImageNumber
иItemId
это мои другие данные, которые мне нужно отправить на сервер, поэтому я также превращаю обе вещи вRequestBody
.Для получения дополнительной информации
источник
Загрузка файлов с использованием Retrofit - это довольно просто. Вам нужно создать интерфейс API как
в приведенном выше коде изображение является именем ключа, поэтому, если вы используете php, вы напишите $ _FILES ['image'] ['tmp_name'], чтобы получить это. И имя файла = "myfile.jpg" - это имя вашего файла, который отправляется с запросом.
Теперь для загрузки файла вам нужен метод, который даст вам абсолютный путь от Uri.
Теперь вы можете использовать приведенный ниже код для загрузки вашего файла.
Для более подробного объяснения вы можете посетить это руководство по загрузке файла дооснащения .
источник
Версия Kotlin с обновлением для удаления
RequestBody.create
:Модифицированный интерфейс
и загрузить
Благодаря @ jimmy0251
источник
Не используйте несколько параметров в имени функции, просто придерживайтесь простого соглашения о нескольких аргументах, которое повысит читабельность кодов , для этого вы можете сделать следующее:
Может быть несколько исключений, с которыми вы можете столкнуться при использовании Retrofit, все исключения, документированные как код , имеют пошаговое руководство
retrofit2/RequestFactory.java
. Вы можете использовать две функции,parseParameterAnnotation
иparseMethodAnnotation
там, где вы можете генерировать исключения, пожалуйста, пройдите через это, это сэкономит вам больше времени, чем поиск в Google / stackoverflowисточник
в kotlin это довольно просто, используя методы расширения toMediaType , asRequestBody и toRequestBody, вот пример:
здесь я публикую несколько нормальных полей вместе с файлом PDF и файлом изображения, используя multipart
это объявление API с использованием модернизации:
и вот как на самом деле это назвать:
источник