通过HTTP的形式上传文件,通过MultipartEntityBuilder,进度条 [英] Upload a file through an HTTP form, via MultipartEntityBuilder, with a progress bar
问题描述
在短版 - 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屋!