Quarkus and Qute Templating Engine: File Upload, Listing, Download & Delete Example

Here is an example of a Quarkus application that implements file upload, listing, downloading, and deleting files using Quarkus Qute templating engine:


1. Add Dependencies to pom.xml

<dependencies>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-qute</artifactId>
    </dependency>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-resteasy-reactive</artifactId>
    </dependency>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-vertx-web</artifactId>
    </dependency>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-smallrye-mutiny</artifactId>
    </dependency>
</dependencies>

2. Create a File Resource Class for Upload, List, Download, and Delete operations

import io.quarkus.qute.Template;
import io.quarkus.qute.TemplateInstance;
import org.jboss.resteasy.reactive.multipart.FileUpload;
import org.jboss.resteasy.reactive.multipart.MultipartForm;
import org.springframework.beans.factory.annotation.Value;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.List;
import java.util.stream.Collectors;

@Path("/files")
public class FileResource {

    @Value("${quarkus.http.host}")
    String host;

    private static final Path UPLOAD_DIR = Paths.get("uploads");

    // Initialize upload directory
    static {
        try {
            if (!Files.exists(UPLOAD_DIR)) {
                Files.createDirectories(UPLOAD_DIR);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Template for listing files
    private final Template fileListTemplate;

    public FileResource(Template fileListTemplate) {
        this.fileListTemplate = fileListTemplate;
    }

    @GET
    @Produces(MediaType.TEXT_HTML)
    public TemplateInstance listFiles() throws IOException {
        List<String> files = Files.walk(UPLOAD_DIR)
                .filter(Files::isRegularFile)
                .map(path -> path.getFileName().toString())
                .collect(Collectors.toList());
        return fileListTemplate.data("files", files);
    }

    // Upload file endpoint
    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public Response uploadFile(@MultipartForm FileUpload file) throws IOException {
        Path filePath = UPLOAD_DIR.resolve(file.fileName());
        Files.copy(file.uploadedFile().toPath(), filePath, StandardCopyOption.REPLACE_EXISTING);
        return Response.ok("File uploaded: " + file.fileName()).build();
    }

    // Download file endpoint
    @GET
    @Path("/download/{filename}")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response downloadFile(@PathParam("filename") String filename) throws IOException {
        Path file = UPLOAD_DIR.resolve(filename);
        if (Files.exists(file)) {
            return Response.ok(file.toFile()).header("Content-Disposition", "attachment; filename=\"" + filename + "\"").build();
        } else {
            return Response.status(Response.Status.NOT_FOUND).build();
        }
    }

    // Delete file endpoint
    @DELETE
    @Path("/delete/{filename}")
    @Produces(MediaType.TEXT_PLAIN)
    public Response deleteFile(@PathParam("filename") String filename) throws IOException {
        Path file = UPLOAD_DIR.resolve(filename);
        if (Files.exists(file)) {
            Files.delete(file);
            return Response.ok("File deleted: " + filename).build();
        } else {
            return Response.status(Response.Status.NOT_FOUND).build();
        }
    }
}

3. Create a Qute Template to Display File List (src/main/resources/templates/file-list.qute.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File List</title>
</head>
<body>
    <h1>File List</h1>
    <ul>
        {#each files}
        <li>
            {it} - <a href="/files/download/{it}">Download</a> | <a href="/files/delete/{it}">Delete</a>
        </li>
        {/each}
    </ul>

    <h2>Upload New File</h2>
    <form action="/files" method="post" enctype="multipart/form-data">
        <input type="file" name="file" required>
        <button type="submit">Upload</button>
    </form>
</body>
</html>

4. Configure Application Properties (src/main/resources/application.properties)

quarkus.http.port=8080
quarkus.http.host=0.0.0.0

5. Run the Application

Run the Quarkus app:

./mvnw quarkus:dev
  • File Upload: You can upload files via the web interface.
  • File List: The list of uploaded files is shown.
  • File Download: You can download files by clicking the respective link.
  • File Delete: You can delete files using the provided delete link.

This basic setup provides file upload, listing, downloading, and deleting features using Quarkus and Qute. You can further enhance this by adding error handling and more complex features.

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete