File Upload with Java (with progress bar)
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.
Asked by: Hailey485 | Posted: 23-01-2022
Answer 1
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.
Answer 2
A simpler countingEntity would not depend on a specific entity type but rather extend HttpEntityWrapped
:
package gr.phaistos.android.util;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.http.HttpEntity;
import org.apache.http.entity.HttpEntityWrapper;
public class CountingHttpEntity extends HttpEntityWrapper {
public static interface ProgressListener {
void transferred(long transferedBytes);
}
static class CountingOutputStream extends FilterOutputStream {
private final ProgressListener listener;
private long transferred;
CountingOutputStream(final OutputStream out, final ProgressListener listener) {
super(out);
this.listener = listener;
this.transferred = 0;
}
@Override
public void write(final byte[] b, final int off, final int len) throws IOException {
//// NO, double-counting, as super.write(byte[], int, int) delegates to write(int).
//super.write(b, off, len);
out.write(b, off, len);
this.transferred += len;
this.listener.transferred(this.transferred);
}
@Override
public void write(final int b) throws IOException {
out.write(b);
this.transferred++;
this.listener.transferred(this.transferred);
}
}
private final ProgressListener listener;
public CountingHttpEntity(final HttpEntity entity, final ProgressListener listener) {
super(entity);
this.listener = listener;
}
@Override
public void writeTo(final OutputStream out) throws IOException {
this.wrappedEntity.writeTo(out instanceof CountingOutputStream? out: new CountingOutputStream(out, this.listener));
}
}
Answered by: Elise414 | Posted: 24-02-2022
Answer 3
I ended up stumbling across an open source Java uploader applet and found everything I needed to know within its code. Here are links to a blog post describing it as well as the source:
Answered by: Roman633 | Posted: 24-02-2022Answer 4
The amount of bytes returned by the listener is different from the original file size. So, instead of having transferred++
, I modified it so that transferred=len
; that is the length of the actual amount of bytes being written to the output stream. And when I compute the addition of the total bytes transferred it is equal to the actual ContentLength
returned by CountingMultiPartEntity.this.getContentLength();
public void write(byte[] b, int off, int len) throws IOException {
wrappedOutputStream_.write(b,off,len);
transferred=len;
listener_.transferred(transferred);
}
Answered by: Carlos189 | Posted: 24-02-2022
Answer 5
Keep in mind that the progress bar might be misleading when an intermediate component in the network (e.g., an ISP's HTTP proxy, or a reverse HTTP proxy in front of the server) consumes your upload faster than the server does.
Answered by: Miller346 | Posted: 24-02-2022Answer 6
As noted by the article Vincent posted, you can use Apache commons to do this.
Little snipped
DiskFileUpload upload = new DiskFileUpload();
upload.setHeaderEncoding(ConsoleConstants.UTF8_ENCODING);
upload.setSizeMax(1000000);
upload.setSizeThreshold(1000000);
Iterator it = upload.parseRequest((HttpServletRequest) request).iterator();
FileItem item;
while(it.hasNext()){
item = (FileItem) it.next();
if (item.getFieldName("UPLOAD FIELD"){
String fileName = item.getString(ConsoleConstants.UTF8_ENCODING);
byte[] fileBytes = item.get();
}
}
Answered by: Luke881 | Posted: 24-02-2022
Answer 7
Just my 2c worth:
This is based off of tuler's answer(has a bug at time of writing). I modified it slightly, so here is my version of tuler and mmyers answer (I can't seem to edit their answer). I wanted to attempt to make this a bit cleaner and faster. Besides the bug(which I discuss in comments on their answer), the big issue I have with their version is that it creates a new CountingOutputStream
with every write. This can get very expensive in terms of memory - tons of allocations and garbage collections. Smaller issue is that is uses a delegate when it could just expand the MultipartEntity
. Not sure why they chose that, so I did it in a manner I was more familiar with. If anyone knows pros/cons of the two approaches that would be great. Finally, the FilterOutputStream#write(byte[], int,int) method just calls the FilterOutputStream#write(byte) in a loop. The FOS documentation recommends subclasses overriding this behavior and making this more efficient. The best way to do that here is to let the underlying OutputStream handle the writing request.
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
public class CountingMultiPartEntity extends MultipartEntity {
private UploadProgressListener listener_;
private CountingOutputStream outputStream_;
private OutputStream lastOutputStream_;
// the parameter is the same as the ProgressListener class in tuler's answer
public CountingMultiPartEntity(UploadProgressListener listener) {
super(HttpMultipartMode.BROWSER_COMPATIBLE);
listener_ = listener;
}
@Override
public void writeTo(OutputStream out) throws IOException {
// If we have yet to create the CountingOutputStream, or the
// OutputStream being passed in is different from the OutputStream used
// to create the current CountingOutputStream
if ((lastOutputStream_ == null) || (lastOutputStream_ != out)) {
lastOutputStream_ = out;
outputStream_ = new CountingOutputStream(out);
}
super.writeTo(outputStream_);
}
private class CountingOutputStream extends FilterOutputStream {
private long transferred = 0;
private OutputStream wrappedOutputStream_;
public CountingOutputStream(final OutputStream out) {
super(out);
wrappedOutputStream_ = out;
}
public void write(byte[] b, int off, int len) throws IOException {
wrappedOutputStream_.write(b,off,len);
++transferred;
listener_.transferred(transferred);
}
public void write(int b) throws IOException {
super.write(b);
}
}
}
Answered by: Anna178 | Posted: 24-02-2022
Answer 8
Look into HTTP Client for uploadign the file to the web. It should be able to to do that. I am unsure how to get the progress bar, but it would involve querying that API somehow.
Answered by: Wilson688 | Posted: 24-02-2022Answer 9
Apache common is very good option. Apache common allows you to configure following things.
- Configure(xml file) the maximum file size/ upload file size
- Destination path (where to save the uploaded file)
- Set the temp. folder to swap the file , so that file upload would be fast.
Answer 10
From the other answers you can just override the AbstractHttpEntity
class children or implementations public void writeTo(OutputStream outstream)
method you are using if do not want to create a class.
An example using a FileEntity
instance:
FileEntity fileEntity = new FileEntity(new File("img.jpg")){
@Override
public void writeTo(OutputStream outstream) throws IOException {
super.writeTo(new BufferedOutputStream(outstream){
int writedBytes = 0;
@Override
public synchronized void write(byte[] b, int off, int len) throws IOException {
super.write(b, off, len);
writedBytes+=len;
System.out.println("wrote: "+writedBytes+"/"+getContentLength()); //Or anything you want [using other threads]
}
});
}
};
Answered by: Roland760 | Posted: 24-02-2022
Similar questions
java - Upload progress bar in DWR?
In my project i want to show the progress bar while uploading files. I am using DWR to get send the data to server, javascript and Java is the server side language. I have done some searches to learn it. But i couldn't able to find one.
Any link to learn or suggestions would be appreciative!!!
Thanks!!
java - How to show file upload progress?
Generally while uploading a file,an uploading type of progress bar is used before clicking on upload buttons in all most all every web.
What exactly we are doing after selecting a file(in that progress bar)
I need to do that using java and jsp or Struts 1.x.
Java upload file with swt progress bar
In my JAVA RCP application I UPLOAD file to a REST API using HTTPPOST.
Now, I want my SWT PROGRESS BAR to connect with the upload file method and display the progress.
I've seen many post on the net and also here on stackover, but none of these post were helpful.
Could anyone help ?
Thanks in advance !
Ismail
java - JavaFX progress bar show file upload status
i am using JavaFX (using scene builder) and i am trying to build a progressBar with a progressIndicator that will show a background file upload status.
Here is my javafx controller (some initialization):
@FXML
private Pane uploadsStatuses;
@FXML
private ProgressBar uploadBar;
@FXML
private ProgressIndicator uploadProgressIndicator;
...
@Override
@FXML
public void initialize(URL url, ResourceBundle r...
swing - Show progress during FTP file upload in a java applet
OK so I have the uploader uploading files using the Java FTP, I would like to update the label and the progress bar. Label with the percent text, bar with the percent int value. Right now with the current code only get the 100 and full bar at the end of the upload. During the upload none of them change.
here it is:
OutputStream output = new BufferedOutputStream(ftpOut);
CopyStreamListener li...
java - File upload progress in spring boot
To upload a file in spring boot one can use something like this:
@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
and ...
java - Progress Dialog in Swing
How can I make a modal JDialog without buttons appear for the duration it takes a Runnable instance to complete and have that instance update a progress bar/message on that dialog?
Clearly spaghetti code might work, but I'm looking for a clean design if one exists.
Command line progress bar in Java
I have a Java program running in command line mode.
I would like to display a progress bar, showing the percentage of job done.
The same kind of progress bar you would see using wget under unix.
Is this possible?
Console based progress in Java
This question already has answers here:
java - Using progress bar in file search
I am writing an application which will search for a particular file or files from the respective path. During searching i need to deploy a progress bar which must run according to the search. so how i can do that? and if possible please post the code?
swing - how can i show progress bar while sending an email in java
hii every one
I want to show progress bar
while my program sends email
how can i do it?
swing - Progress bar in Java
I have got a form in Java (Swing) loading large amount of data from the database. I want to display a progress bar while the program gets actually loaded.
How can i do it?
The code is as follows:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.sql.*;
import java.applet.*;
import java.util.*;
import java.awt.Color;
public class bookshow extends JFrame implement...
progress bar - Getting scp's status bar to appear in a Java window
I'm writing a program that uses scp to copy files in a bigger java program. As it stands now, the program freezes up while the scp is copying the file, which can take a few minutes, so I'd like to be able to display the progress of the scp or at the very least get the terminal window with the scp progress to show up! Any suggestions?
java - jre 1.6 check and progress bar in inno
I want to check whether hre 1.6 or higher is installed or not. If installed I want to progress my application. If not installed , I want to install jre-6u17-windows-i586-s.exe after successfully installing jre , my control not returns to inno again. Please send a inno script for that.
best regards
SOumen
java - Progress Dialog in Android doesn't Show?
Okay.. I am doing something similar to the below:
private void onCreate() {
final ProgressDialog dialog = ProgressDialog.show(this, "Please wait..", "Doing stuff..", true);
Thread t = new Thread() {
public void run() {
//do some serious stuff...
dialog.dismiss();
}
};
t.start();
t.join();
stepTwo();
}
However, what I am finding is that my progress d...
java - Progress bar while applet loads
OK so, let's say I have a Java applet that takes a while to load (~5 secs). It's getting the mysql-connector.jar and it's loading. Well.. instead of the gray box with the coffee logo... can I make it have a simple progress bar with the percent?
Thanks.
Still can't find your answer? Check out these amazing Java communities for help...
Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)