File Upload with Java (with progress bar)

soapergem picture soapergem · Oct 31, 2008 · Viewed 57.5k times · Source

I'm extremely new to Java, and have mostly just been teaching myself as I go, so I've started building an applet. I'd like to make one that can select a file from the local disk and upload it as a multipart/form-data POST request but with a progress bar. Obviously the user has to grant permission to the Java applet to access the hard drive. Now I've already got the first part working: the user can select a file using a JFileChooser object, which conveniently returns a File object. But I'm wondering what comes next. I know that File.length() will give me the total size in bytes of the file, but how do I send the selected File to the web, and how do I monitor how many bytes have been sent? Thanks in advance.

Answer

tuler picture tuler · Jan 22, 2009

To check progress using HttpClient, wrap the MultipartRequestEntity around one that counts the bytes being sent. Wrapper is below:

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.httpclient.methods.RequestEntity;

public class CountingMultipartRequestEntity implements RequestEntity {
    private final RequestEntity delegate;

    private final ProgressListener listener;

    public CountingMultipartRequestEntity(final RequestEntity entity,
            final ProgressListener listener) {
        super();
        this.delegate = entity;
        this.listener = listener;
    }

    public long getContentLength() {
        return this.delegate.getContentLength();
    }

    public String getContentType() {
        return this.delegate.getContentType();
    }

    public boolean isRepeatable() {
        return this.delegate.isRepeatable();
    }

    public void writeRequest(final OutputStream out) throws IOException {
        this.delegate.writeRequest(new CountingOutputStream(out, this.listener));
    }

    public static interface ProgressListener {
        void transferred(long num);
    }

    public static class CountingOutputStream extends FilterOutputStream {

        private final ProgressListener listener;

        private long transferred;

        public CountingOutputStream(final OutputStream out,
                final ProgressListener listener) {
            super(out);
            this.listener = listener;
            this.transferred = 0;
        }

        public void write(byte[] b, int off, int len) throws IOException {
            out.write(b, off, len);
            this.transferred += len;
            this.listener.transferred(this.transferred);
        }

        public void write(int b) throws IOException {
            out.write(b);
            this.transferred++;
            this.listener.transferred(this.transferred);
        }
    }
}

Then implements a ProgressListener which updates a progress bar.
Remember that the progress bar update must not run on the Event Dispatch Thread.