【问题标题】:Sending multipart POST data without external libraries在没有外部库的情况下发送多部分 POST 数据
【发布时间】:2014-05-14 15:28:32
【问题描述】:

我的 Android 应用架构基于 DefaultHttpClient。大约 2 天前,我标头他们正在改进 HttpURLConnection,我正要更改整个架构以使用它,但似乎代码重写太多,所以我坚持使用 DefaultHttpClient

现在我必须上传一个multipart 实体,我一直在阅读有关从Apache 添加一个名为mime 的外部库的信息,该库恰好被弃用

我的问题是,有没有办法使用AndroidJava SDK 发送multipart 实体?因为如果没有,我想我会把它全部改成HttpURLConnection

【问题讨论】:

标签: java android httpurlconnection apache-httpclient-4.x


【解决方案1】:

您可以尝试一些我为我的项目编写的课程。多部分表单类是一个非常简单的实现,但它应该很容易被破解以适应发送数据数组或任何你需要的东西。

/**
 * Used to provide an interface for sending post data of various types.
 */
public interface PostData {
    /**
     * Add the specified field to the post data.
     *
     * @param name The name or title of the field.
     * @param value The value of the field.
     * @return This object (for streamed programming)
     */
    public PostData addField(String name, String value);
    /**
     * End the data.
     */
    public PostData end();

    public String getContentType();
    public String toString();
    public int getLength();
}


/**
 * Generate a multi-part form to post data.
 */
public static class MultiPartForm implements PostData {
    private final static String boundary = "AaBbC0xQrpqqqqqqqq";
    private StringBuilder sb = new StringBuilder();

    public PostData addField(String name, String value) {
        sb.append("--")
            .append(boundary)
            .append("\nContent-Disposition: form-data; name='")
            .append(name)
            .append("'\n\n")
            .append(value)
            .append("\n");
        return this;
    }

    public PostData end() {
        sb.append("--").append(boundary).append("--");
        return this;
    }

    public final String getContentType() {
        return "multipart/form-data;boundary=" + boundary;
    }

    public String toString() {
        return sb.toString();
    }

    public int getLength() {
        return sb.length();
    }
}


/**
 * Creates URL encoded data.
 * Does not include the question mark at the beginning of the string.
 */
public static class UrlEncodedData implements PostData {
    private StringBuilder sb = new StringBuilder();

    public PostData addField(String name, String value) {
        if (sb.length() > 0) {
            sb.append("&");
        }
        try {
            sb.append(URLEncoder.encode(name, "UTF-8"))
                .append("=")
                .append(URLEncoder.encode(value, "UTF-8"));
        // Shouldn't ever happen.
        } catch (java.io.UnsupportedEncodingException e) {}
        return this;
    }

    public PostData end() {
        return this;
    }

    public final String getContentType() {
        return "application/x-www-form-urlencoded";
    }

    public String toString() {
        return sb.toString();
    }

    public int getLength() {
        return sb.length();
    }
}

除此之外,我还创建了一种方法来使检索数据更加简单。我将 HttpURLConnection 与此方法一起使用,但要了解如何使用 DefaultHttpClient 执行相同操作的要点应该非常简单。请注意,它是同步的,因此您必须在另一个线程中调用它:

/**
 * Loads a specified URL with the params incoded in the post.
 * 
 * @throws Exception For numerous reasons.
 * @param url The base URL to connect to.
 * @param data A PostData object to fetch. Specifiy null for a GET request.
 * @return The result.
 */
public static String loadUrl(final String url, final PostData data)
        throws Exception {
    HttpURLConnection urlConnection = null;
    BufferedReader br = null;
    final StringBuilder result = new StringBuilder();

    try {
        urlConnection = (HttpURLConnection)new URL(url).openConnection();

        if (data != null) {
            urlConnection.setRequestMethod("POST");;
            urlConnection.setRequestProperty("Content-Type", data.getContentType());
            urlConnection.setRequestProperty("Content-Length",
                Integer.toString(data.getLength()));
            urlConnection.setDoOutput(true);

            DataOutputStream dos = new DataOutputStream(
                urlConnection.getOutputStream());
            dos.writeBytes(data.toString());
            dos.flush();
            dos.close();

            urlConnection.connect();
        }

        br = new BufferedReader(
            new InputStreamReader(urlConnection.getInputStream()));

        String line;
        while ((line = br.readLine()) != null) {
            result.append(line);
        }
    } finally {
        try { urlConnection.disconnect(); } catch (Exception e) {}
        try { br.close(); } catch (Exception e) {}
    }

    return result.toString();
}

用法相当琐碎:

Utils.loadUrl("someApi.com/foobar/"
    new Utils.MultiPartForm()
        .addField("first_name", "John")
        .addField("last_name", "Doe")
        .end());

【讨论】:

    猜你喜欢
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 2015-11-12
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多