跳转至

Android HttpURLConnection POST 上传文件

更新日期:2023-3-23
  • 2023-3-23 更新说明
  • 2023-3-9 创建文档

HttpURLConnection POST上传文件和参数

使用HttpURLConnection创建连接,传递参数和文件。

package com.kct.sdk.util;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

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);

        FileInputStream fis = new FileInputStream(uploadFile);
        byte[] bytes = new byte[10240];
        int length = 0;
        int len;
        for (; (len = fis.read(bytes, 0, 10240)) != -1; length += len) {
            if (len < 10240) {
                ++len;
            }
            request.write(bytes, 0, len);
        }
        fis.close();
        request.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 {
        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;
    }
}

上面的代码 MultipartUtilityV2(String requestURL) 中:

  • 创建一个URL对象,URL为requestURL。
  • 打开一个HTTP连接并将其赋值给httpConn。
  • 禁用缓存。
  • 启用输出流,指示使用POST方法。
  • 启用输入流。
  • 设置请求方法为POST。
  • 设置连接属性Connection为Keep-Alive。
  • 设置连接属性Cache-Control为no-cache。
  • 设置请求头Content-Type为multipart/form-data,并指定边界为this.boundary。

addFilePart方法用于将文件添加到HTTP请求中的 multipart/form-data 部分。 具体来说,该方法接收两个参数:fieldName表示HTTP请求中指定文件上传的字段名,uploadFile表示要上传的文件对象。

该方法的执行过程如下:

  • 获取上传文件的文件名。
  • 写入 multipart/form-data 部分的边界和Content-Disposition头部信息,指定name为fieldName,filename为fileName。
  • 写入回车换行符。
  • 打开一个输入流读取上传文件的内容,每次读取10240字节数据,并将读取到的数据写入HTTP请求输出流中。
  • 关闭输入流并清空输出流。

使用示例,放在子线程中进行

try {
    MultipartUtilityV2 multipartUtilityV2 = new MultipartUtilityV2(url); // 目标接口
    multipartUtilityV2.addFormField("key1", "RustFisher"); // 自定义参数
    multipartUtilityV2.addFormField("work", "an.rustfisher.com");
    multipartUtilityV2.addFilePart("file", file); // 要上传的文件 file
    String resStr = multipartUtilityV2.finish();
    // 检查返回的结果
} catch (Exception e) {
    // 异常处理
}

参考

https://stackoverflow.com/questions/11766878/sending-files-using-post-with-httpurlconnection

本站说明

一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~

📖AndroidTutorial 📚AndroidTutorial 🙋反馈问题 🔥最近更新 🍪投喂作者

Ads