How to send a “multipart/form-data” POST in Android with Volley

后端 未结 9 2298
不思量自难忘°
不思量自难忘° 2020-11-22 03:50

Has anyone been able to accomplish sending a multipart/form-data POST in Android with Volley yet? I have had no success trying to upload an image/png

9条回答
  •  眼角桃花
    2020-11-22 04:33

    Complete Multipart Request with Upload Progress

    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FilterOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.mime.HttpMultipartMode;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.entity.mime.content.FileBody;
    import org.apache.http.util.CharsetUtils;
    
    import com.android.volley.AuthFailureError;
    import com.android.volley.NetworkResponse;
    import com.android.volley.Request;
    import com.android.volley.Response;
    import com.android.volley.VolleyLog;
    import com.beusoft.app.AppContext;
    
    public class MultipartRequest extends Request {
    
        MultipartEntityBuilder entity = MultipartEntityBuilder.create();
        HttpEntity httpentity;
        private String FILE_PART_NAME = "files";
    
        private final Response.Listener mListener;
        private final File mFilePart;
        private final Map mStringPart;
        private Map headerParams;
        private final MultipartProgressListener multipartProgressListener;
        private long fileLength = 0L;
    
        public MultipartRequest(String url, Response.ErrorListener errorListener,
                Response.Listener listener, File file, long fileLength,
                Map mStringPart,
                final Map headerParams, String partName,
                MultipartProgressListener progLitener) {
            super(Method.POST, url, errorListener);
    
            this.mListener = listener;
            this.mFilePart = file;
            this.fileLength = fileLength;
            this.mStringPart = mStringPart;
            this.headerParams = headerParams;
            this.FILE_PART_NAME = partName;
            this.multipartProgressListener = progLitener;
    
            entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            try {
                entity.setCharset(CharsetUtils.get("UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            buildMultipartEntity();
            httpentity = entity.build();
        }
    
        // public void addStringBody(String param, String value) {
        // if (mStringPart != null) {
        // mStringPart.put(param, value);
        // }
        // }
    
        private void buildMultipartEntity() {
            entity.addPart(FILE_PART_NAME, new FileBody(mFilePart, ContentType.create("image/gif"), mFilePart.getName()));
            if (mStringPart != null) {
                for (Map.Entry entry : mStringPart.entrySet()) {
                    entity.addTextBody(entry.getKey(), entry.getValue());
                }
            }
        }
    
        @Override
        public String getBodyContentType() {
            return httpentity.getContentType().getValue();
        }
    
        @Override
        public byte[] getBody() throws AuthFailureError {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                httpentity.writeTo(new CountingOutputStream(bos, fileLength,
                        multipartProgressListener));
            } catch (IOException e) {
                VolleyLog.e("IOException writing to ByteArrayOutputStream");
            }
            return bos.toByteArray();
        }
    
        @Override
        protected Response parseNetworkResponse(NetworkResponse response) {
    
            try {
    //          System.out.println("Network Response "+ new String(response.data, "UTF-8"));
                return Response.success(new String(response.data, "UTF-8"),
                        getCacheEntry());
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                // fuck it, it should never happen though
                return Response.success(new String(response.data), getCacheEntry());
            }
        }
    
        @Override
        protected void deliverResponse(String response) {
            mListener.onResponse(response);
        }
    
    //Override getHeaders() if you want to put anything in header
    
        public static interface MultipartProgressListener {
            void transferred(long transfered, int progress);
        }
    
        public static class CountingOutputStream extends FilterOutputStream {
            private final MultipartProgressListener progListener;
            private long transferred;
            private long fileLength;
    
            public CountingOutputStream(final OutputStream out, long fileLength,
                    final MultipartProgressListener listener) {
                super(out);
                this.fileLength = fileLength;
                this.progListener = listener;
                this.transferred = 0;
            }
    
            public void write(byte[] b, int off, int len) throws IOException {
                out.write(b, off, len);
                if (progListener != null) {
                    this.transferred += len;
                    int prog = (int) (transferred * 100 / fileLength);
                    this.progListener.transferred(this.transferred, prog);
                }
            }
    
            public void write(int b) throws IOException {
                out.write(b);
                if (progListener != null) {
                    this.transferred++;
                    int prog = (int) (transferred * 100 / fileLength);
                    this.progListener.transferred(this.transferred, prog);
                }
            }
    
        }
    }
    

    Sample Usage

    protected  void uploadFile(final String tag, final String url,
                final File file, final String partName,         
                final Map headerParams,
                final Response.Listener resultDelivery,
                final Response.ErrorListener errorListener,
                MultipartProgressListener progListener) {
            AZNetworkRetryPolicy retryPolicy = new AZNetworkRetryPolicy();
    
            MultipartRequest mr = new MultipartRequest(url, errorListener,
                    resultDelivery, file, file.length(), null, headerParams,
                    partName, progListener);
    
            mr.setRetryPolicy(retryPolicy);
            mr.setTag(tag);
    
            Volley.newRequestQueue(this).add(mr);
    
        }
    

提交回复
热议问题