1. ホーム
  2. android

[解決済み] HTTP フォームから MultipartEntityBuilder 経由でファイルをアップロードする(プログレスバー付き)。

2022-02-14 05:26:34

質問

ショートバージョン - org.apache...MultipartEntity は非推奨であり、そのアップグレード版。 MultipartEntityBuilder は、私たちのオンライン・フォーラムであまり紹介されていないようです。それを解決しましょう。私の(Android)アプリがファイルをアップロードするときにプログレスバーを表示できるように、コールバックをどのように登録するのですか?

その ロングバージョン - 以下は、quot;missing dirt-simple example" の例です。 MultipartEntityBuilder :

public static void postFile(String fileName) throws Exception {
    // Based on: https://stackoverflow.com/questions/2017414/post-multipart-request-with-android-sdk

    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(SERVER + "uploadFile");
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
    builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    builder.addPart("file", new FileBody(new File(fileName)));
    builder.addTextBody("userName", userName);
    builder.addTextBody("password", password);
    builder.addTextBody("macAddress", macAddress);
    post.setEntity(builder.build());
    HttpResponse response = client.execute(post);
    HttpEntity entity = response.getEntity();

    // response.getStatusLine();  // CONSIDER  Detect server complaints

    entity.consumeContent();
    client.getConnectionManager().shutdown(); 

}  // FIXME  Hook up a progress bar!

を修正する必要があります。 FIXME . (追加的な利点は、中断可能なアップロードです。) しかし、(私が間違っているかどうか訂正してください)、オンラインの例はすべて不足しているようです。

これですね。 http://pastebin.com/M0uNZ6SB は、例えば、ファイルをアップロードする際、"binary/octet-stream"; multipart/form-data" ではなく、"binary/form-data" としてアップロードします。実際のフィールドが必要なのです。

この例では Javaによるファイルアップロード(プログレスバー付き) をオーバーライドする方法を示しています。 *Entity または *Stream . ということで、もしかしたら MultipartEntityBuilder から .create() アップロードの進捗を測定するオーバーライドされたエンティティ?

もし私が何かをオーバーライドして、組み込みのストリームを1000バイトごとにシグナルを送るカウントストリームに置き換えたいのであれば、おそらく FileBody の部分をオーバーライドし、その getInputStream および writeTo .

しかし、私が試したところ class ProgressiveFileBody extends FileBody {...} という悪名高き java.lang.NoClassDefFoundError .

だから、私の周りをスペランキングしている間に .jar ファイルから、足りないDefを探し出すのですが、どなたか私の計算をチェックして、私が見落としているもっと簡単な修正を指摘していただけないでしょうか?

解決方法は?

優勝したコードは(壮大なJava-Heresy(tm)スタイルで)です。

public static String postFile(String fileName, String userName, String password, String macAddress) throws Exception {

    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(SERVER + "uploadFile");
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
    builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

    final File file = new File(fileName);
    FileBody fb = new FileBody(file);

    builder.addPart("file", fb);  
    builder.addTextBody("userName", userName);
    builder.addTextBody("password", password);
    builder.addTextBody("macAddress",  macAddress);
    final HttpEntity yourEntity = builder.build();

    class ProgressiveEntity implements HttpEntity {
        @Override
        public void consumeContent() throws IOException {
            yourEntity.consumeContent();                
        }
        @Override
        public InputStream getContent() throws IOException,
                IllegalStateException {
            return yourEntity.getContent();
        }
        @Override
        public Header getContentEncoding() {             
            return yourEntity.getContentEncoding();
        }
        @Override
        public long getContentLength() {
            return yourEntity.getContentLength();
        }
        @Override
        public Header getContentType() {
            return yourEntity.getContentType();
        }
        @Override
        public boolean isChunked() {             
            return yourEntity.isChunked();
        }
        @Override
        public boolean isRepeatable() {
            return yourEntity.isRepeatable();
        }
        @Override
        public boolean isStreaming() {             
            return yourEntity.isStreaming();
        } // CONSIDER put a _real_ delegator into here!

        @Override
        public void writeTo(OutputStream outstream) throws IOException {

            class ProxyOutputStream extends FilterOutputStream {
                /**
                 * @author Stephen Colebourne
                 */

                public ProxyOutputStream(OutputStream proxy) {
                    super(proxy);    
                }
                public void write(int idx) throws IOException {
                    out.write(idx);
                }
                public void write(byte[] bts) throws IOException {
                    out.write(bts);
                }
                public void write(byte[] bts, int st, int end) throws IOException {
                    out.write(bts, st, end);
                }
                public void flush() throws IOException {
                    out.flush();
                }
                public void close() throws IOException {
                    out.close();
                }
            } // CONSIDER import this class (and risk more Jar File Hell)

            class ProgressiveOutputStream extends ProxyOutputStream {
                public ProgressiveOutputStream(OutputStream proxy) {
                    super(proxy);
                }
                public void write(byte[] bts, int st, int end) throws IOException {

                    // FIXME  Put your progress bar stuff here!

                    out.write(bts, st, end);
                }
            }

            yourEntity.writeTo(new ProgressiveOutputStream(outstream));
        }

    };
    ProgressiveEntity myEntity = new ProgressiveEntity();

    post.setEntity(myEntity);
    HttpResponse response = client.execute(post);        

    return getContent(response);

} 

public static String getContent(HttpResponse response) throws IOException {
    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    String body = "";
    String content = "";

    while ((body = rd.readLine()) != null) 
    {
        content += body + "\n";
    }
    return content.trim();
}

#  NOTE ADDED LATER: as this blasterpiece gets copied into various code lineages, 
#  The management reminds the peanut gallery that "Java-Heresy" crack was there
#  for a reason, and (as commented) most of that stuff can be farmed out to off-
#  the-shelf jar files and what-not. That's for the java lifers to tool up. This
#  pristine hack shall remain obviousized for education, and for use in a pinch.

#  What are the odds??