I've got the following code for a file upload with Apache's HTTP-Client (org.apache.http.client):
public static void main(String[] args) throws Exception
{
String fileName = "test.avi";
File file = new File(fileName);
String serverResponse = null;
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPut put = new HttpPut("http://localhost:8080/" + fileName);
FileEntity fileEntity = new FileEntity(file, "binary/octet-stream");
put.setEntity(fileEntity);
HttpResponse response = client.execute(put);
HttpEntity entity = response.getEntity();
if (entity != null)
{
serverResponse = EntityUtils.toString(entity);
System.out.println(serverResponse);
}
}
It work's quite well but now I want to have a progress bar which shows the progress of the file upload. How can this be made? I found a code snippet at File Upload with Java (with progress bar) but it is designed for Apache HTTP Client 3 (org.apache.commons.httpclient) and the RequestEntity class does not exist in Apache HTTP Client 4. ;(
Maybe someone of you has an approach?
Many greetings
Benny
A new version using the package org.apache.commons.io.output from commons-io (2.4) and its class CountingOutputStream.
I changed the initial code to reflect my project needs to use a multipart form as input and the post method (this dues to the requirements imposed by the server side).
Consider that the delta of large file correspond in my tests to 4096 bytes. This means that the listener method counterChanged() is called every 4096 bytes of transfered data, what is acceptable for my use case.
The method looks like:
The class MyFileBody becomes:
Finally, the listener interface looks like:
I introduced a derived
FileEntity
that just counts the written bytes. It usesOutputStreamProgress
that does the actual counting (kind of a decorator to the actualOutputStream
).The advantage of this (and decoration in general) is that I do not need to copy the actual implementation, like the the actual copying from the file stream to the output stream. I can also change to use a different (newer) implementation, like the
NFileEntity
.Enjoy...
FileEntity.java
OutputStreamProgress.java
This answer extends kilaka's answer by adding a simple listener to the OutputStreamProgress.java class instead of having the public getProgress() method (I'm honestly not sure how you are suppose to call the getProgress() method since the thread will be executing inside of httpclient's code the entire time you might want to call getProgress()!).
Please note you'll need to extend the entity class for each entity type you want to use, and when you write your HttpClient code, you'll need to create the entity of that new type.
I wrote a very basic write listener that implements the WriteListener interface. This is where you'll add your logic to do something with the write reports from the OutputStreamProgress, something like updating a progress bar :)
Big thanks to kilaka for using the decorator idea to sneak in a counting outstream.
WriteLisener.java
OutputStreamProgress.java
BasicWriteListener
MultipartEntityWithProgressBar
Hello guys!
I solved the problem myself and made a simple example to it.
If there are any questions, feel free to ask.
Here we go!
ApplicationView.java
FileEntityWithProgressBar.java
ProgressBarListener.java
Happy Coding!