通过HTTP的形式上传文件,通过MultipartEntityBuilder,进度条 [英] Upload a file through an HTTP form, via MultipartEntityBuilder, with a progress bar

查看:252
本文介绍了通过HTTP的形式上传文件,通过MultipartEntityBuilder,进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

短版 - org.apache ... MultipartEntity 是德precated,它的升级, MultipartEntityBuilder ,出现在-RE presented在我们的网上论坛。让我们来解决这个问题。怎样才能注册一个回调,所以我(安卓)的应用程序可以显示一个进度条,因为它上传文件?

The short version - org.apache...MultipartEntity is deprecated, and its upgrade, MultipartEntityBuilder, appears under-represented in our online forums. Let's fix that. How does one register a callback, so my (Android) app can display a progress bar as it uploads a file?

长版 - 下面是失踪污垢简单的例子, MultipartEntityBuilder

The long version - Here's the "missing dirt-simple example" of MultipartEntityBuilder:

public static void postFile(String fileName) throws Exception {
    // Based on: http://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 。 (另外一个好处是可中断上传)。但是(请纠正我,我是否错了),所有的在线例子似乎功亏一篑。

We need to fix that FIXME. (An added benefit would be interruptible uploads.) But (please correct me whether or not I'm wrong), all the online examples seem to fall short.

这一次, http://pastebin.com/M0uNZ6SB ,例如,上传文件为二进制/八位字节流;不是的multipart / form-data的。我需要真正的领域。

This one, http://pastebin.com/M0uNZ6SB, for example, uploads a file as a "binary/octet-stream"; not a "multipart/form-data". I require real fields.

这个例子中,文件上传与Java(带进度条),说明如何重写 *实体 *流。所以也许我可以告诉 MultipartEntityBuilder .create()一个重写的实体米,它的上传进度?

This example, File Upload with Java (with progress bar), shows how to override the *Entity or the *Stream. So maybe I can tell the MultipartEntityBuilder to .create() an overridden entity that meters its upload progress?

所以,如果我要重写的东西,并更换内置的流,这发出了一个信号,每1000字节计数流,也许我能延长 FileBody 部分,并覆盖其的getInputStream 和/或的writeTo

So if I want to override something, and replace the built-in stream with a counting stream that sends a signal for every 1000 bytes, maybe I can extend the FileBody part, and override its getInputStream and/or writeTo.

但是当我尝试类ProgressiveFileBody扩展FileBody {...} ,我得到的臭名昭著的 java.lang.NoClassDefFoundError的

But when I try class ProgressiveFileBody extends FileBody {...}, I get the infamous java.lang.NoClassDefFoundError.

所以,当我去洞穴探险在我的的.jar 文件,寻找失踪闪避,有人可以检查我的数学,也许指出一个简单的修复我忽略了?

So while I go spelunking around my .jar files, looking for the missing Def, can someone check my math, and maybe point out a simpler fix I have overlooked?

推荐答案

获奖code(壮观的Java的异端(TM)的方式)是:

The winning code (in spectacular Java-Heresy(tm) style) is:

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??

这篇关于通过HTTP的形式上传文件,通过MultipartEntityBuilder,进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆