首页 文章

使用带HttpURLConnection的POST发送文件

提问于
浏览
112

由于Android开发人员recommend使用 HttpURLConnection 类,我想知道是否有人能够提供一个关于如何通过POST将位图"file"(实际上是内存中的流)发送到Apache HTTP服务器的好例子 . 我在这里看到的'm not interested in cookies or authentication or anything complicated, but I just want to have a reliable and logic implementation. All the examples that I'看起来更像"let's try this and maybe it works" .

现在,我有这个代码:

URL url;
HttpURLConnection urlConnection = null;
try {
    url = new URL("http://example.com/server.cgi");

    urlConnection = (HttpURLConnection) url.openConnection();

} catch (Exception e) {
    this.showDialog(getApplicationContext(), e.getMessage());
}
finally {
    if (urlConnection != null)
    {
        urlConnection.disconnect();
    }
}

showDialog应该只显示 AlertDialog (如果URL无效?) .

现在,假设我生成一个如此的位图: Bitmap image = this.getBitmap() 在一个从 View 派生的控件中,我想通过POST发送它 . 实现这样的事情的正确程序是什么?我需要使用哪些课程?我能在_1362686中使用 HttpPost 吗?如果是这样,我将如何为我的位图构建 InputStreamEntity ?我觉得要首先将位图存储在设备上的文件中是令人反感的 .


我还要提一下,我真的需要将原始位图的每个未经改变的像素发送到服务器,因此我无法将其转换为JPEG .

10 回答

  • 1

    我不知道为什么 HttpURLConnection 类没有提供任何手段来发送文件而不必手动编写文件包装器 . 这是我最终做的事情,但如果有人知道更好的解决方案,请告诉我 .

    输入数据:

    Bitmap bitmap = myView.getBitmap();
    

    静电东西:

    String attachmentName = "bitmap";
    String attachmentFileName = "bitmap.bmp";
    String crlf = "\r\n";
    String twoHyphens = "--";
    String boundary =  "*****";
    

    设置请求:

    HttpURLConnection httpUrlConnection = null;
    URL url = new URL("http://example.com/server.cgi");
    httpUrlConnection = (HttpURLConnection) url.openConnection();
    httpUrlConnection.setUseCaches(false);
    httpUrlConnection.setDoOutput(true);
    
    httpUrlConnection.setRequestMethod("POST");
    httpUrlConnection.setRequestProperty("Connection", "Keep-Alive");
    httpUrlConnection.setRequestProperty("Cache-Control", "no-cache");
    httpUrlConnection.setRequestProperty(
        "Content-Type", "multipart/form-data;boundary=" + this.boundary);
    

    启动内容包装器:

    DataOutputStream request = new DataOutputStream(
        httpUrlConnection.getOutputStream());
    
    request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
    request.writeBytes("Content-Disposition: form-data; name=\"" +
        this.attachmentName + "\";filename=\"" + 
        this.attachmentFileName + "\"" + this.crlf);
    request.writeBytes(this.crlf);
    

    Bitmap 转换为 ByteBuffer

    //I want to send only 8 bit black & white bitmaps
    byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
    for (int i = 0; i < bitmap.getWidth(); ++i) {
        for (int j = 0; j < bitmap.getHeight(); ++j) {
            //we're interested only in the MSB of the first byte, 
            //since the other 3 bytes are identical for B&W images
            pixels[i + j] = (byte) ((bitmap.getPixel(i, j) & 0x80) >> 7);
        }
    }
    
    request.write(pixels);
    

    结束内容包装器:

    request.writeBytes(this.crlf);
    request.writeBytes(this.twoHyphens + this.boundary + 
        this.twoHyphens + this.crlf);
    

    刷新输出缓冲区:

    request.flush();
    request.close();
    

    得到回应:

    InputStream responseStream = new 
        BufferedInputStream(httpUrlConnection.getInputStream());
    
    BufferedReader responseStreamReader = 
        new BufferedReader(new InputStreamReader(responseStream));
    
    String line = "";
    StringBuilder stringBuilder = new StringBuilder();
    
    while ((line = responseStreamReader.readLine()) != null) {
        stringBuilder.append(line).append("\n");
    }
    responseStreamReader.close();
    
    String response = stringBuilder.toString();
    

    关闭响应流:

    responseStream.close();
    

    关闭连接:

    httpUrlConnection.disconnect();
    

    PS:当然我必须在 private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String> 中包装请求,以使Android平台满意,因为它不喜欢在主线程上有网络请求 .

  • 0

    我实际上找到了一种使用MultipartEntity使用HttpURLConnection发送文件的更好方法

    private static String multipost(String urlString, MultipartEntity reqEntity) {
        try {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setUseCaches(false);
            conn.setDoInput(true);
            conn.setDoOutput(true);
    
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.addRequestProperty("Content-length", reqEntity.getContentLength()+"");
            conn.addRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue());
    
            OutputStream os = conn.getOutputStream();
            reqEntity.writeTo(conn.getOutputStream());
            os.close();
            conn.connect();
    
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                return readStream(conn.getInputStream());
            }
    
        } catch (Exception e) {
            Log.e(TAG, "multipart post error " + e + "(" + urlString + ")");
        }
        return null;        
    }
    
    private static String readStream(InputStream in) {
        BufferedReader reader = null;
        StringBuilder builder = new StringBuilder();
        try {
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return builder.toString();
    }
    

    假设您要上传包含位图数据的图像:

    Bitmap bitmap = ...;
        String filename = "filename.png";
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
        ContentBody contentPart = new ByteArrayBody(bos.toByteArray(), filename);
    
        MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        reqEntity.addPart("picture", contentPart);
        String response = multipost("http://server.com", reqEntity);
    

    还有瞧!您的帖子数据将包含图片字段以及服务器上的文件名和路径 .

  • 2

    使用 MultipartUtility 以简单的方式使用某个参数在服务器上上载文件 .

    MultipartUtility.java

    public class MultipartUtility {
    
        private final String boundary;
        private static final String LINE_FEED = "\r\n";
        private HttpURLConnection httpConn;
        private String charset;
        private OutputStream outputStream;
        private PrintWriter writer;
    
        /**
         * This constructor initializes a new HTTP POST request with content type
         * is set to multipart/form-data
         *
         * @param requestURL
         * @param charset
         * @throws IOException
         */
        public MultipartUtility(String requestURL, String charset)
                throws IOException {
            this.charset = charset;
    
            // creates a unique boundary based on time stamp
            boundary = "===" + System.currentTimeMillis() + "===";
    
            URL url = new URL(requestURL);
            Log.e("URL", "URL : " + requestURL.toString());
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setUseCaches(false);
            httpConn.setDoOutput(true); // indicates POST method
            httpConn.setDoInput(true);
            httpConn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + boundary);
            httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
            httpConn.setRequestProperty("Test", "Bonjour");
            outputStream = httpConn.getOutputStream();
            writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                    true);
        }
    
        /**
         * Adds a form field to the request
         *
         * @param name  field name
         * @param value field value
         */
        public void addFormField(String name, String value) {
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
                    .append(LINE_FEED);
            writer.append("Content-Type: text/plain; charset=" + charset).append(
                    LINE_FEED);
            writer.append(LINE_FEED);
            writer.append(value).append(LINE_FEED);
            writer.flush();
        }
    
        /**
         * Adds a upload file section to the request
         *
         * @param fieldName  name attribute in <input type="file" name="..." />
         * @param uploadFile a File to be uploaded
         * @throws IOException
         */
        public void addFilePart(String fieldName, File uploadFile)
                throws IOException {
            String fileName = uploadFile.getName();
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append(
                    "Content-Disposition: form-data; name=\"" + fieldName
                            + "\"; filename=\"" + fileName + "\"")
                    .append(LINE_FEED);
            writer.append(
                    "Content-Type: "
                            + URLConnection.guessContentTypeFromName(fileName))
                    .append(LINE_FEED);
            writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
            writer.append(LINE_FEED);
            writer.flush();
    
            FileInputStream inputStream = new FileInputStream(uploadFile);
            byte[] buffer = new byte[4096];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            inputStream.close();
    
            writer.append(LINE_FEED);
            writer.flush();
        }
    
        /**
         * Adds a header field to the request.
         *
         * @param name  - name of the header field
         * @param value - value of the header field
         */
        public void addHeaderField(String name, String value) {
            writer.append(name + ": " + value).append(LINE_FEED);
            writer.flush();
        }
    
        /**
         * Completes the request and receives response from the server.
         *
         * @return a list of Strings as response in case the server returned
         * status OK, otherwise an exception is thrown.
         * @throws IOException
         */
        public String finish() throws IOException {
            StringBuffer response = new StringBuffer();
    
            writer.append(LINE_FEED).flush();
            writer.append("--" + boundary + "--").append(LINE_FEED);
            writer.close();
    
            // checks server's status code first
            int status = httpConn.getResponseCode();
            if (status == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        httpConn.getInputStream()));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                reader.close();
                httpConn.disconnect();
            } else {
                throw new IOException("Server returned non-OK status: " + status);
            }
    
            return response.toString();
        }
    }
    

    uploadfile 以及参数 .

    注意:将此代码放在非ui-thread中以获得响应 .

    String charset = "UTF-8";
    String requestURL = "YOUR_URL";
    
    MultipartUtility multipart = new MultipartUtility(requestURL, charset);
    multipart.addFormField("param_name_1", "param_value");
    multipart.addFormField("param_name_2", "param_value");
    multipart.addFormField("param_name_3", "param_value");
    multipart.addFilePart("file_param_1", new File(file_path));
    String response = multipart.finish(); // response from server.
    
  • 0

    Jaydipsinh Zala 的解决方案没有知道为什么,因为它似乎太接近解决方案了 .

    所以我把这个与 Mihai Todor 的伟大解决方案和解释合并,现在这个类适合我 . 如果有人帮助:

    MultipartUtility2V.java

    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.nio.file.Files;
    
    public class MultipartUtilityV2 {
        private HttpURLConnection httpConn;
        private DataOutputStream request;
        private final String boundary =  "*****";
        private final String crlf = "\r\n";
        private final String twoHyphens = "--";
    
        /**
         * This constructor initializes a new HTTP POST request with content type
         * is set to multipart/form-data
         *
         * @param requestURL
         * @throws IOException
         */
        public MultipartUtilityV2(String requestURL)
                throws IOException {
    
            // creates a unique boundary based on time stamp
            URL url = new URL(requestURL);
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setUseCaches(false);
            httpConn.setDoOutput(true); // indicates POST method
            httpConn.setDoInput(true);
    
            httpConn.setRequestMethod("POST");
            httpConn.setRequestProperty("Connection", "Keep-Alive");
            httpConn.setRequestProperty("Cache-Control", "no-cache");
            httpConn.setRequestProperty(
                    "Content-Type", "multipart/form-data;boundary=" + this.boundary);
    
            request =  new DataOutputStream(httpConn.getOutputStream());
        }
    
        /**
         * Adds a form field to the request
         *
         * @param name  field name
         * @param value field value
         */
        public void addFormField(String name, String value)throws IOException  {
            request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
            request.writeBytes("Content-Disposition: form-data; name=\"" + name + "\""+ this.crlf);
            request.writeBytes("Content-Type: text/plain; charset=UTF-8" + this.crlf);
            request.writeBytes(this.crlf);
            request.writeBytes(value+ this.crlf);
            request.flush();
        }
    
        /**
         * Adds a upload file section to the request
         *
         * @param fieldName  name attribute in <input type="file" name="..." />
         * @param uploadFile a File to be uploaded
         * @throws IOException
         */
        public void addFilePart(String fieldName, File uploadFile)
                throws IOException {
            String fileName = uploadFile.getName();
            request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
            request.writeBytes("Content-Disposition: form-data; name=\"" +
                    fieldName + "\";filename=\"" +
                    fileName + "\"" + this.crlf);
            request.writeBytes(this.crlf);
    
            byte[] bytes = Files.readAllBytes(uploadFile.toPath());
            request.write(bytes);
        }
    
        /**
         * Completes the request and receives response from the server.
         *
         * @return a list of Strings as response in case the server returned
         * status OK, otherwise an exception is thrown.
         * @throws IOException
         */
        public String finish() throws IOException {
            String response ="";
    
            request.writeBytes(this.crlf);
            request.writeBytes(this.twoHyphens + this.boundary +
                    this.twoHyphens + this.crlf);
    
            request.flush();
            request.close();
    
            // checks server's status code first
            int status = httpConn.getResponseCode();
            if (status == HttpURLConnection.HTTP_OK) {
                InputStream responseStream = new
                        BufferedInputStream(httpConn.getInputStream());
    
                BufferedReader responseStreamReader =
                        new BufferedReader(new InputStreamReader(responseStream));
    
                String line = "";
                StringBuilder stringBuilder = new StringBuilder();
    
                while ((line = responseStreamReader.readLine()) != null) {
                    stringBuilder.append(line).append("\n");
                }
                responseStreamReader.close();
    
                response = stringBuilder.toString();
                httpConn.disconnect();
            } else {
                throw new IOException("Server returned non-OK status: " + status);
            }
    
            return response;
        }
    }
    
  • 179

    基于Mihai的解决方案,如果有人在服务器上保存图像的问题,就像在我的服务器上发生的那样 . 将位图更改为bytebuffer部分:

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);
            byte[] pixels = bos.toByteArray();
    
  • 63

    我没有测试过这个,但您可以尝试使用PipedInputStream和PipedOutputStream . 它可能看起来像:

    final Bitmap bmp = … // your bitmap
    
    // Set up Piped streams
    final PipedOutputStream pos = new PipedOutputStream(new ByteArrayOutputStream());
    final PipedInputStream pis = new PipedInputStream(pos);
    
    // Send bitmap data to the PipedOutputStream in a separate thread
    new Thread() {
        public void run() {
            bmp.compress(Bitmap.CompressFormat.PNG, 100, pos);
        }
    }.start();
    
    // Send POST request
    try {
        // Construct InputStreamEntity that feeds off of the PipedInputStream
        InputStreamEntity reqEntity = new InputStreamEntity(pis, -1);
    
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(url);
        reqEntity.setContentType("binary/octet-stream");
        reqEntity.setChunked(true);
        httppost.setEntity(reqEntity);
        HttpResponse response = httpclient.execute(httppost);
    } catch (Exception e) {
        e.printStackTrace()
    }
    
  • 7

    这个答案让我在将大型文件上传到开发Django服务器的过程中占了90%,但我不得不使用setFixedLengthStreamingMode来使其工作 . 这需要在写入内容之前设置内容长度,因此需要对上述答案进行相当重要的重写 . 这是我的最终结果

    public class MultipartLargeUtility {
        private final String boundary;
        private static final String LINE_FEED = "\r\n";
        private HttpURLConnection httpConn;
        private String charset;
        private OutputStream outputStream;
        private PrintWriter writer;
        private final int maxBufferSize = 4096;
        private long contentLength = 0;
        private URL url;
    
        private List<FormField> fields;
        private List<FilePart> files;
    
        private class FormField {
            public String name;
            public String value;
    
            public FormField(String name, String value) {
                this.name = name;
                this.value = value;
            }
        }
    
        private class FilePart {
            public String fieldName;
            public File uploadFile;
    
            public FilePart(String fieldName, File uploadFile) {
                this.fieldName = fieldName;
                this.uploadFile = uploadFile;
            }
        }
    
        /**
         * This constructor initializes a new HTTP POST request with content type
         * is set to multipart/form-data
         *
         * @param requestURL
         * @param charset
         * @throws IOException
         */
        public MultipartLargeUtility(String requestURL, String charset, boolean requireCSRF)
                throws IOException {
            this.charset = charset;
    
            // creates a unique boundary based on time stamp
            boundary = "===" + System.currentTimeMillis() + "===";
            url = new URL(requestURL);
            fields = new ArrayList<>();
            files = new ArrayList<>();
    
            if (requireCSRF) {
                getCSRF();
            }
        }
    
        /**
         * Adds a form field to the request
         *
         * @param name  field name
         * @param value field value
         */
        public void addFormField(String name, String value)
                throws UnsupportedEncodingException {
            String fieldContent = "--" + boundary + LINE_FEED;
            fieldContent += "Content-Disposition: form-data; name=\"" + name + "\"" + LINE_FEED;
            fieldContent += "Content-Type: text/plain; charset=" + charset + LINE_FEED;
            fieldContent += LINE_FEED;
            fieldContent += value + LINE_FEED;
            contentLength += fieldContent.getBytes(charset).length;
            fields.add(new FormField(name, value));
        }
    
        /**
         * Adds a upload file section to the request
         *
         * @param fieldName  name attribute in <input type="file" name="..." />
         * @param uploadFile a File to be uploaded
         * @throws IOException
         */
        public void addFilePart(String fieldName, File uploadFile)
                throws IOException {
            String fileName = uploadFile.getName();
    
            String fieldContent = "--" + boundary + LINE_FEED;
            fieldContent += "Content-Disposition: form-data; name=\"" + fieldName
                    + "\"; filename=\"" + fileName + "\"" + LINE_FEED;
            fieldContent += "Content-Type: "
                    + URLConnection.guessContentTypeFromName(fileName) + LINE_FEED;
            fieldContent += "Content-Transfer-Encoding: binary" + LINE_FEED;
            fieldContent += LINE_FEED;
            // file content would go here
            fieldContent += LINE_FEED;
            contentLength += fieldContent.getBytes(charset).length;
            contentLength += uploadFile.length();
            files.add(new FilePart(fieldName, uploadFile));
        }
    
        /**
         * Adds a header field to the request.
         *
         * @param name  - name of the header field
         * @param value - value of the header field
         */
        //public void addHeaderField(String name, String value) {
        //    writer.append(name + ": " + value).append(LINE_FEED);
        //    writer.flush();
        //}
    
        /**
         * Completes the request and receives response from the server.
         *
         * @return a list of Strings as response in case the server returned
         * status OK, otherwise an exception is thrown.
         * @throws IOException
         */
        public List<String> finish() throws IOException {
            List<String> response = new ArrayList<String>();
            String content = "--" + boundary + "--" + LINE_FEED;
            contentLength += content.getBytes(charset).length;
    
            if (!openConnection()) {
                return response;
            }
    
            writeContent();
    
            // checks server's status code first
            int status = httpConn.getResponseCode();
            if (status == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        httpConn.getInputStream()));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    response.add(line);
                }
                reader.close();
                httpConn.disconnect();
            } else {
                throw new IOException("Server returned non-OK status: " + status);
            }
            return response;
        }
    
        private boolean getCSRF()
                throws IOException {
            /// First, need to get CSRF token from server
            /// Use GET request to get the token
            CookieManager cookieManager = new CookieManager();
            CookieHandler.setDefault(cookieManager);
            HttpURLConnection conn = null;
    
            conn = (HttpURLConnection) url.openConnection();
    
            conn.setUseCaches(false); // Don't use a Cached Copy
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.getContent();
            conn.disconnect();
    
            /// parse the returned object for the CSRF token
            CookieStore cookieJar = cookieManager.getCookieStore();
            List<HttpCookie> cookies = cookieJar.getCookies();
            String csrf = null;
            for (HttpCookie cookie : cookies) {
                Log.d("cookie", "" + cookie);
                if (cookie.getName().equals("csrftoken")) {
                    csrf = cookie.getValue();
                    break;
                }
            }
            if (csrf == null) {
                Log.d(TAG, "Unable to get CSRF");
                return false;
            }
            Log.d(TAG, "Received cookie: " + csrf);
    
            addFormField("csrfmiddlewaretoken", csrf);
            return true;
        }
    
        private boolean openConnection()
                throws IOException {
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setUseCaches(false);
            httpConn.setDoOutput(true);    // indicates POST method
            httpConn.setDoInput(true);
            //httpConn.setRequestProperty("Accept-Encoding", "identity");
            httpConn.setFixedLengthStreamingMode(contentLength);
            httpConn.setRequestProperty("Connection", "Keep-Alive");
            httpConn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + boundary);
            outputStream = new BufferedOutputStream(httpConn.getOutputStream());
            writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                    true);
            return true;
        }
    
        private void writeContent()
                throws IOException {
    
            for (FormField field : fields) {
                writer.append("--" + boundary).append(LINE_FEED);
                writer.append("Content-Disposition: form-data; name=\"" + field.name + "\"")
                        .append(LINE_FEED);
                writer.append("Content-Type: text/plain; charset=" + charset).append(
                        LINE_FEED);
                writer.append(LINE_FEED);
                writer.append(field.value).append(LINE_FEED);
                writer.flush();
            }
    
            for (FilePart filePart : files) {
                String fileName = filePart.uploadFile.getName();
                writer.append("--" + boundary).append(LINE_FEED);
                writer.append(
                        "Content-Disposition: form-data; name=\"" + filePart.fieldName
                                + "\"; filename=\"" + fileName + "\"")
                        .append(LINE_FEED);
                writer.append(
                        "Content-Type: "
                                + URLConnection.guessContentTypeFromName(fileName))
                        .append(LINE_FEED);
                writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
                writer.append(LINE_FEED);
                writer.flush();
    
                FileInputStream inputStream = new FileInputStream(filePart.uploadFile);
                int bufferSize = Math.min(inputStream.available(), maxBufferSize);
                byte[] buffer = new byte[bufferSize];
                int bytesRead = -1;
                while ((bytesRead = inputStream.read(buffer, 0, bufferSize)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
                inputStream.close();
                writer.append(LINE_FEED);
                writer.flush();
            }
    
            writer.append("--" + boundary + "--").append(LINE_FEED);
            writer.close();
        }
    }
    

    用法与上面的答案大致相同,但我已经包含了Django默认使用表单的CSRF支持

    boolean useCSRF = true;
    MultipartLargeUtility multipart = new MultipartLargeUtility(url, "UTF-8",useCSRF);
    multipart.addFormField("param1","value");
    multipart.addFilePart("filefield",new File("/path/to/file"));
    List<String> response = multipart.finish();
    Log.w(TAG,"SERVER REPLIED:");
    for(String line : response) {
        Log.w(TAG, "Upload Files Response:::" + line);
    }
    
  • 52

    这是我使用帖子请求上传照片所做的 .

    public void uploadFile(int directoryID, String filePath) {
        Bitmap bitmapOrg = BitmapFactory.decodeFile(filePath);
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
    
        String upload_url = BASE_URL + UPLOAD_FILE;
        bitmapOrg.compress(Bitmap.CompressFormat.JPEG, 90, bao);
    
        byte[] data = bao.toByteArray();
    
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost postRequest = new HttpPost(upload_url);
        MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    
        try {
            // Set Data and Content-type header for the image
            FileBody fb = new FileBody(new File(filePath), "image/jpeg");
            StringBody contentString = new StringBody(directoryID + "");
    
            entity.addPart("file", fb);
            entity.addPart("directory_id", contentString);
            postRequest.setEntity(entity);
    
            HttpResponse response = httpClient.execute(postRequest);
            // Read the response
            String jsonString = EntityUtils.toString(response.getEntity());
            Log.e("response after uploading file ", jsonString);
    
        } catch (Exception e) {
            Log.e("Error in uploadFile", e.getMessage());
        }
    }
    

    NOTE: 此代码需要库,因此请按照here的说明获取库 .

  • 0

    我发现使用okHttp要容易得多,因为我无法使用任何这些解决方案:https://stackoverflow.com/a/37942387/447549

  • 1

    我尝试了上面的解决方案,没有一个能为我开箱即用 .

    但是http://www.baeldung.com/httpclient-post-http-request . 第6行POST多部分请求在几秒钟内完成

    public void whenSendMultipartRequestUsingHttpClient_thenCorrect() 
      throws ClientProtocolException, IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost("http://www.example.com");
    
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addTextBody("username", "John");
        builder.addTextBody("password", "pass");
        builder.addBinaryBody("file", new File("test.txt"),
          ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    
        HttpEntity multipart = builder.build();
        httpPost.setEntity(multipart);
    
        CloseableHttpResponse response = client.execute(httpPost);
        client.close();
    }
    

相关问题