Multipart Request using Retrofit 1.8.0 not working

前端 未结 3 1011
名媛妹妹
名媛妹妹 2021-01-12 19:25

I have like 4 days, trying to make a Multipart Request using Retrofit 1.8.0 in android with any success. My interface looks something like this

@Multipart
@         


        
相关标签:
3条回答
  • 2021-01-12 20:08

    I had similar problem today to send file and some fields, here is my solution

    My interface, TypedFile is a Retrofit class

        @Multipart
        @POST("/api/Media/add")
        void addMedia(@Part("file") TypedFile photo,
                      @Part("type") String type,
                      @Part("name") String name,
                      @Part("description") String description,
                      Callback<com.yourcompany.pojo.Media> callback);
    

    in Activity

    profileImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent galleryIntent = new Intent(
                        Intent.ACTION_PICK,
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(galleryIntent , RESULT_GALLERY );
            }
        });
    

    and then

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
        switch (requestCode) {
            case RESULT_GALLERY :
                if (null != data) {
                    imageUri = data.getData();
                    String selectedImagePath = null;
                    Uri selectedImageUri = data.getData();
                    Cursor cursor = activity.getContentResolver().query(selectedImageUri, null, null,
                    null, null);
                    if (cursor == null) {
                        selectedImagePath = imageUri.getPath();
                    } else {
                        cursor.moveToFirst();
                        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                        selectedImagePath = cursor.getString(idx);
                    }
                    File file = new File(selectedImagePath);
                    waiter.setVisibility(View.VISIBLE);
                    _YOUR_APP_._YOUR_INTERFACE_.addMedia(new TypedFile("image/*", file), "avatar", "avatar", "avatar", new Callback<Media>() {
    
                        @Override
                        public void success(Media media, Response response) {
    
                        }
    
                        @Override
                        public void failure(RetrofitError error) {
    
                        }
                    });
                }
                break;
            default:
                break;
        }
    }
    

    Media class is simple pojo to keep answer

    public class Media {
    
    @Expose
    private int[] data;
    
    /**
     *
     * @return
     * The data
     */
    public int getData() {
        return data[0];
    }
    
    /**
     *
     * @param data
     * The data
     */
    public void setData(int[] data) {
        this.data = data;
    }
    
    }
    
    0 讨论(0)
  • 2021-01-12 20:18

    I did this instead for the interface

    interface MultipartFormDataService {
        @POST("/{uploadPath}")
        void multipartFormDataSend(
                @EncodedPath("uploadPath") String uploadPath,
                @Body MultipartTypedOutput multipartTypedOutput,
                Callback<String> cb);
    }
    

    Then later when I call it, it looks like this

    // creating the Multipart body using retrofit
    MultipartTypedOutput multipartTypedOutput = new MultipartTypedOutput();
    TypedString idParam = new TypedString("[ID Value]")
    TypedString bodyParam = new TypedString("[Body text]")
    ByteArrayTypedOutput byteMultipartTypedOut = new ByteArrayTypedOutput(bytes)
    
    // add parts
    multipartTypedOutput.addPart("id", idParam);
    multipartTypedOutput.addPart("body", bodyParam);
    multipartTypedOutput.addPart("attachment", extraParamTypedString);
    
    // send
    multipartService.multipartFormDataSend(
                    "[TARGET URL]",
                    multipartTypedOutput,
                aCallback);
    

    My ByteArrayTypedOutput was simple

    public class ByteArrayTypedOutput implements TypedOutput {
    
        private MultipartFormMetadata metadata;
        private byte[] imageData;
    
        public ByteArrayTypedOutput(MultipartFormMetadata metadata, byte[] imageData)
            this.metadata = metadata;
            this.imageData = imageData;
        }
    
        @Override
        public String fileName() {
            return metadata.fileName;
        }
    
        @Override
        public String mimeType() {
            return metadata.fileMimeType;
        }
    
        @Override
        public long length() {
            return imageData.length;
        }
    
        @Override
        public void writeTo(OutputStream outputStream) throws IOException {
             outputStream.write(imageData);
        }
    }
    
    0 讨论(0)
  • 2021-01-12 20:25

    If you see the examples on http://square.github.io/retrofit/ the object types for your "id" and "part[body]" parameters need to be TypedString and not String. TypedString sets the appropriate MIME type and does the conversion to bytes:

    https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/mime/TypedString.java

    0 讨论(0)
提交回复
热议问题