AndroidはMultipartEntityBuilderを使用してformフォームの提出方式のようなファイルアップロードを実現


最近Android側のファイルアップロードをしていて、formフォームで提出するように要求されています.プロジェクトで使用するafinalフレームワークにはファイルアップロード機能がありますが、phpで書かれたサービス側と接続できず、アップロードに成功できません.ソースコードを読むと、afinalはある大神が書いたMultipartEntityを使っていた.JAvaはformフォームのコンテンツを生成しますが、生成されたコンテンツのフォーマットが標準的ではなく、まずすべてのファイルをメモリに読み込み、バイトストリームをsocketに書き込むなど、多くの問題があります.では、何百MBのファイルならどうしますか.
いくつかの検索で、この文章(転載されたが、サンプルコードが期限切れになった)に啓発され、Apacheソースhttpcomponents-client-4.3を見つけた.6-src.zipは、1つの例で重要なコンポーネントMultipartEntity Builderを発見しました.formフォーム形式のHttpEntityを生成することができます.HttpEntityがあれば、どんなhttpフレームワークでも使用できるはずです.
どうやって使うのか分かりません.like this:
HttpPost httppost = new HttpPost(url);
...
final HttpEntity entity = makeMultipartEntity(params, files);
httppost.addHeader(entity.getContentType());
//httppost.addHeader(entity.getContentEncoding());    //null
httppost.setEntity(entity);
HttpResponse response = getHttpClient().execute(httppost);
...

private static HttpClient mClient;
private static HttpClient getHttpClient() {
    if(mClient == null) {
        //if(Build.VERSION.SDK_INT >= 9);    //      Case,  HttpURLConnection
        if(Build.VERSION.SDK_INT >= 8) {
            mClient = AndroidHttpClient.newInstance(getUserAgent());
        }else {
            mClient = new DefaultHttpClient();
        }
    }
    return mClient;
}

MultipartEntityBuilderの使い方は以下のように整理されています.
httpcomponents-client-4.3が必要である.6-bin.zipのhttpmime-4.3.6.jarとhttpcore-4.3.3.jar
public static HttpEntity makeMultipartEntity(List<NameValuePair> params, final Map<String, File> files) {
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);	//   SocketTimeoutException   ,       
    //builder.setCharset(Charset.forName("UTF-8"));	//     ,            
    if (params != null && params.size() > 0) {
        for (NameValuePair p : params) {
            builder.addTextBody(p.getName(), p.getValue(), ContentType.TEXT_PLAIN.withCharset("UTF-8"));
        }
    }
    if (files != null && files.size() > 0) {
        Set<Entry<String, File>> entries = files.entrySet();
        for (Entry<String, File> entry : entries) {
            builder.addPart(entry.getKey(), new FileBody(entry.getValue()));
        }
    }
    return builder.build();
}

Apacheの例を添付、httpcomponents-client-4.3.6-bin.zipで見つかりました.
/*
 * ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */
package org.apache.http.examples.entity.mime;

import java.io.File;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * Example how to use multipart/form encoded POST request.
 */
public class ClientMultipartFormPost {

    public static void main(String[] args) throws Exception {
        if (args.length != 1)  {
            System.out.println("File path not given");
            System.exit(1);
        }
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost("http://localhost:8080" +
                    "/servlets-examples/servlet/RequestInfoExample");

            FileBody bin = new FileBody(new File(args[0]));
            StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);

            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("bin", bin)
                    .addPart("comment", comment)
                    .build();


            httppost.setEntity(reqEntity);

            System.out.println("executing request " + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}