Próbuję wykonać HTTP POST do serwera przy użyciu 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();
Serwer zwraca błąd informujący, że plik jest nieprawidłowy.
To dziwne, ponieważ próbowałem przesłać ten sam plik w tym samym formacie na iOS (przy użyciu innej biblioteki), ale pomyślnie się przesyła.
Zastanawiam się, jaki jest właściwy sposób wgrania obrazu za pomocą Retrofit 2.0 ?
Czy powinienem najpierw zapisać go na dysku przed załadowaniem?
PS: Użyłem modernizacji dla innego żądania Multipart, które nie zawiera obrazu i zakończyło się pomyślnie. Problem pojawia się, gdy próbuję dołączyć bajt do treści.
android
retrofit
androidhttpclient
retrofit2
JayVDiyk
źródło
źródło
Odpowiedzi:
Podkreślam rozwiązanie w obu 1.9 i 2.0, ponieważ jest przydatne dla niektórych
W
1.9
, myślę, że lepszym rozwiązaniem jest, aby zapisać plik na dysku i używać go jako plik Typed jak:RetroFit 1.9.0
(Nie wiem o twojej implementacji po stronie serwera) mam podobną metodę interfejsu API
I używaj tego jak
W przypadku RetroFit 2 Użyj następującej metody
RetroFit 2.0 (było to obejście problemu w RetroFit 2, który jest teraz naprawiony, aby uzyskać poprawną metodę, zapoznaj się z odpowiedzią jimmy0251 )
Interfejs API:
Używaj go jak:
źródło
@Multipart @POST("/api/Accounts/editaccount") Call<User> editUser(@PartMap Map<String, RequestBody> params);
I kiedy masz plik:Map<String, RequestBody> map = new HashMap<>(); RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpg"), file); map.put("file\"; filename=\"" + file.getName(), fileBody);
MultiPartBody.Part
Istnieje poprawny sposób wgrania pliku z jego nazwą za pomocą Retrofit 2 , bez żadnego włamania :
Zdefiniuj interfejs API:
Prześlij plik w ten sposób:
Pokazuje to tylko przesyłanie plików, możesz również dodać inne parametry w ten sam sposób z
@Part
adnotacją.źródło
MultipartBody.Part
tym samym interfejsie API można używać wielu argumentów.@Part("images[]") List<MultipartBody.Part> images
ale daje to błąd@Part parameters using the MultipartBody.Part must not include a part name
@Body MultipartBody multipartBody
iMultipartBody.Builder
do wysyłania kolekcji obrazów.Użyłem Retrofit 2.0 dla moich zarejestrowanych użytkowników, wysłałem obraz pliku wieloczęściowego / formularza i tekst z konta rejestru
W moim RegisterActivity użyj AsyncTask
A w mojej klasie Register.java jest użycie Retrofit z połączeniem synchronicznym
W interfejsie RegisterService
Dla analizy składniowej Utilities ofr InputStream
źródło
Zaktualizuj kod do przesyłania plików graficznych w Retrofit2.0
Zmień
MediaType.parse("image/*")
naMediaType.parse("image/jpeg")
źródło
@Multipart
wówczas@Part
adnotacja musi zawierać nazwę lub użyć typu parametru MultipartBody.Part.@Part("profile_pic\"; filename=\"pp.png "
Dodanie do odpowiedzi udzielonej przez @insomniac . Możesz utworzyć,
Map
aby umieścić parametrRequestBody
dołączania obrazu.Kod interfejsu
Kod klasy Java
źródło
Jest to więc bardzo prosty sposób na wykonanie zadania. Musisz wykonać poniższy krok: -
1. Pierwszy krok
Musisz wykonać całe połączenie jako
@Multipart request
.item
iimage number
jest po prostu zawiniętym ciałem ze sznurkaRequestBody
. Używamy tego,MultipartBody.Part class
który pozwala nam przesłać wraz z żądaniem rzeczywistą nazwę pliku oprócz binarnych danych pliku2. Krok drugi
Teraz masz
image path
i musisz przekonwertować nafile
.Teraz przekonwertowaćfile
naRequestBody
metodę usingRequestBody.create(MediaType.parse("multipart/form-data"), file)
. Teraz musisz przekonwertować swoją metodęRequestBody requestFile
naMultipartBody.Part
usingMultipartBody.Part.createFormData("Image", file.getName(), requestBody);
.ImageNumber
iItemId
to moje kolejne dane, które muszę wysłać na serwer, więc robię też obie rzeczyRequestBody
.Po więcej informacji
źródło
Przesyłanie plików za pomocą Retrofit jest dość proste. Musisz zbudować interfejs API jako
na powyższym obrazku kodu jest nazwa klucza, więc jeśli używasz php, napiszesz $ _FILES ['image'] ['tmp_name'], aby to uzyskać. I nazwa_pliku = „mojplik.jpg” to nazwa twojego pliku, który jest wysyłany z żądaniem.
Teraz, aby przesłać plik, potrzebujesz metody, która poda bezwzględną ścieżkę z Uri.
Teraz możesz użyć poniższego kodu, aby przesłać plik.
Bardziej szczegółowe wyjaśnienia można znaleźć w tym samouczku dotyczącym przesyłania plików do modernizacji .
źródło
Wersja Kotlin z aktualizacją do usuwania
RequestBody.create
:Interfejs do modernizacji
i przesłać
Dzięki @ jimmy0251
źródło
Nie używaj wielu parametrów w nazwie funkcji, po prostu idź z prostą konwencją kilku argumentów, która zwiększy czytelność kodów , w tym celu możesz zrobić:
Nie może być kilka wyjątków, które mogą się pojawić podczas korzystania modernizowanych wszystkich wyjątków udokumentowanych jako kod , mają do instruktażu
retrofit2/RequestFactory.java
. możesz mieć dwie funkcjeparseParameterAnnotation
iparseMethodAnnotation
gdzie możesz wyrzucić wyjątek, przejdź przez to, zaoszczędzi to dużo czasu niż google / stackoverflowźródło
w kotlin jest to całkiem proste, używając metod rozszerzeń toMediaType , asRequestBody i toRequestBody. Oto przykład:
tutaj zamieszczam kilka normalnych pól wraz z plikiem pdf i plikiem obrazu przy użyciu multipart
to jest deklaracja API przy użyciu retrofitu:
a oto jak to nazwać:
źródło