This guide demonstrates how to create a web app that enables users to upload and download files to and from the server in Java.
In this guide, we create a web app that enables users to upload and download files to and from the server. The UI allows users to select local files to be uploaded to the server. Once a file upload is completed, the UI offers a link allowing users to download the file back from the server. The web app is developed entirely in Java using Vaadin Flow (no HTML or JavaScript involved). You can explore the full source code on GitHub.
What You Need
- About 10 minutes
- JDK 8 or later
Import a starter project
- Download a starter project by clicking the following button
- Unzip the starter and open the project in your favorite IDE.
Create Upload Area
Let’s start by creating the part of the UI that allows users to upload files to the server. The UploadArea
class extends VerticalLayout
, and it acts as a container holding two components: an Upload
and a Span
. The Upload
component, uploadField
, is one of Vaadin’s components that enable users to, well, upload files. The Span
, errorField
, is used to show users informative error messages in the event that something goes wrong during the upload process.
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.upload.MultiFileReceiver;
import com.vaadin.flow.component.upload.Receiver;
import com.vaadin.flow.component.upload.Upload;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class UploadArea extends VerticalLayout {
private final Upload uploadField;
private final Span errorField;
public UploadArea(File uploadFolder) {
uploadField = new Upload(createFileReceiver(uploadFolder));
uploadField.setMaxFiles(100);
// set max file size to 1 MB
uploadField.setMaxFileSize(1 * 1024 * 1024);
uploadField.setDropLabel(new Label("Drop file here (max 1MB)"));
errorField = new Span();
errorField.setVisible(false);
errorField.getStyle().set("color", "red");
uploadField.addFailedListener(e -> showErrorMessage(e.getReason().getMessage()));
uploadField.addFileRejectedListener(e -> showErrorMessage(e.getErrorMessage()));
add(uploadField, errorField);
}
public Upload getUploadField() {
return uploadField;
}
public void hideErrorField() {
errorField.setVisible(false);
}
private Receiver createFileReceiver(File uploadFolder) {
return (MultiFileReceiver) (filename, mimeType) -> {
File file = new File(uploadFolder, filename);
try {
return new FileOutputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
return null;
}
};
}
private void showErrorMessage(String message) {
errorField.setVisible(true);
errorField.setText(message);
}
}
Create Download-Links Area
Next, we create the part of the UI that lists the download links to the user. The DownloadLinksArea
class also extends the VerticalLayout
component, and it adds a link to the UI for each file that exists inside the upload folder.
import com.vaadin.flow.component.html.Anchor;
import com.vaadin.flow.component.html.H4;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.server.StreamResource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DownloadLinksArea extends VerticalLayout {
private final File uploadFolder;
public DownloadLinksArea(File uploadFolder) {
this.uploadFolder = uploadFolder;
refreshFileLinks();
setMargin(true);
}
public void refreshFileLinks() {
removeAll();
add(new H4("Download Links:"));
for (File file : uploadFolder.listFiles()) {
addLinkToFile(file);
}
}
private void addLinkToFile(File file) {
StreamResource streamResource = new StreamResource(file.getName(), () -> getStream(file));
Anchor link = new Anchor(streamResource, String.format("%s (%d KB)", file.getName(),
(int) file.length() / 1024));
link.getElement().setAttribute("download", true);
add(link);
}
private InputStream getStream(File file) {
FileInputStream stream = null;
try {
stream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return stream;
}
}
Create the Main View
Now we create the view that holds the upload and download-links area. This view is itself yet another VerticalLayout
, and it is made accessible to the end user via the @Route
annotation (in this case, it would be accessible via the empty route).
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import java.io.File;
@Route("")
public class UploadDownloadView extends VerticalLayout {
public UploadDownloadView() {
File uploadFolder = getUploadFolder();
UploadArea uploadArea = new UploadArea(uploadFolder);
DownloadLinksArea linksArea = new DownloadLinksArea(uploadFolder);
uploadArea.getUploadField().addSucceededListener(e -> {
uploadArea.hideErrorField();
linksArea.refreshFileLinks();
});
add(uploadArea, linksArea);
}
private static File getUploadFolder() {
File folder = new File("uploaded-files");
if (!folder.exists()) {
folder.mkdirs();
}
return folder;
}
}
Run the Application
To run the project from the command line, type mvnw spring-boot:run
(on Windows), or ./mvnw spring-boot:run
(on macOS or Linux).
Then, in your browser, open http://localhost:8080.
Summary
Congratulations! You have created a web app that enables users to upload and download files to and from the server in Java. And you did it in pure Java, without the need to use HTML or JavaScript, and without the need to expose REST services or think about HTTP requests, responses, and filter chains.
You can explore the full source code on GitHub.
See also
- More configurations and use-cases of the Upload UI Component
- Create new projects at start.vaadin.com
- Read the documentation at vaadin.com/docs
- Training videos and certifications
- Vaadin Flow In-Depth Tutorial