Vue.js Spring Boot: File Upload, List, Download, and Delete


Here's a detailed guide to implement a file upload, listing, downloading, and deleting functionality using Vue.js as the frontend and Spring Boot as the backend.

Overview:

  1. Backend (Spring Boot):

    • Handle file upload, download, list, and delete functionality.
    • Store files in a database or filesystem (we will use database for this example).
  2. Frontend (Vue.js):

    • Provide UI to upload, list, download, and delete files.

Step 1: Spring Boot Backend

1.1 Create Spring Boot Application

You can use Spring Initializr to create a Spring Boot project with the following dependencies:

  • Spring Web
  • Spring Data JPA (for database integration)
  • H2 Database (for simplicity, you can use other databases like MySQL, PostgreSQL, etc.)
  • Lombok (optional for easier code writing)
  • Spring Boot DevTools (for easier development)

1.2 Backend Project Structure

  1. FileEntity: A model representing the uploaded file.
  2. FileRepository: JPA repository to handle database operations.
  3. FileService: Service class to handle file operations.
  4. FileController: REST controller to expose file operations via HTTP.

1.3 FileEntity Class (Model)

package com.example.fileupload.model;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import java.util.UUID;

@Entity
public class FileEntity {

    @Id
    private String id = UUID.randomUUID().toString();
    private String name;

    @Lob
    private byte[] content;

    // Constructors, getters, and setters
    public FileEntity() {}

    public FileEntity(String name, byte[] content) {
        this.name = name;
        this.content = content;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }
}

1.4 FileRepository Interface

package com.example.fileupload.repository;

import com.example.fileupload.model.FileEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface FileRepository extends JpaRepository<FileEntity, String> {
}

1.5 FileService Class

package com.example.fileupload.service;

import com.example.fileupload.model.FileEntity;
import com.example.fileupload.repository.FileRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

@Service
public class FileService {

    @Autowired
    private FileRepository fileRepository;

    // Upload a file
    public FileEntity uploadFile(MultipartFile file) throws IOException {
        FileEntity fileEntity = new FileEntity(file.getOriginalFilename(), file.getBytes());
        return fileRepository.save(fileEntity);
    }

    // Get all files
    public List<FileEntity> getAllFiles() {
        return fileRepository.findAll();
    }

    // Get a file by ID
    public Optional<FileEntity> getFileById(String id) {
        return fileRepository.findById(id);
    }

    // Delete a file by ID
    public void deleteFileById(String id) {
        fileRepository.deleteById(id);
    }
}

1.6 FileController Class

package com.example.fileupload.controller;

import com.example.fileupload.model.FileEntity;
import com.example.fileupload.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/files")
public class FileController {

    @Autowired
    private FileService fileService;

    // Upload a file
    @PostMapping("/upload")
    public ResponseEntity<FileEntity> uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        FileEntity uploadedFile = fileService.uploadFile(file);
        return ResponseEntity.ok(uploadedFile);
    }

    // List all files
    @GetMapping
    public List<FileEntity> getAllFiles() {
        return fileService.getAllFiles();
    }

    // Download a file
    @GetMapping("/{id}")
    public ResponseEntity<byte[]> downloadFile(@PathVariable String id) {
        Optional<FileEntity> fileEntityOpt = fileService.getFileById(id);
        if (fileEntityOpt.isPresent()) {
            FileEntity fileEntity = fileEntityOpt.get();
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileEntity.getName() + "\"")
                    .body(fileEntity.getContent());
        }
        return ResponseEntity.notFound().build();
    }

    // Delete a file by ID
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteFile(@PathVariable String id) {
        fileService.deleteFileById(id);
        return ResponseEntity.noContent().build();
    }
}

1.7 Application Properties

If you're using H2 as the database, make sure your application.properties file is configured like this:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update

1.8 Run Your Spring Boot Application

Run the Spring Boot application. It will be available on http://localhost:8080.

Step 2: Vue.js Frontend

2.1 Set Up Vue.js Project

If you don't have Vue CLI installed, you can install it with the following command:

npm install -g @vue/cli

Create a new Vue project:

vue create file-upload
cd file-upload

2.2 Install Axios

To handle HTTP requests, install Axios:

npm install axios

2.3 Create the Vue Component

In src/components/FileUpload.vue, create the file upload, list, download, and delete functionality.

<template>
  <div>
    <h1>File Upload</h1>

    <!-- Upload Form -->
    <form @submit.prevent="uploadFile">
      <input type="file" @change="onFileChange" />
      <button type="submit" :disabled="!file">Upload</button>
    </form>

    <!-- File List -->
    <h2>Files</h2>
    <ul>
      <li v-for="file in files" :key="file.id">
        {{ file.name }}
        <button @click="downloadFile(file.id)">Download</button>
        <button @click="deleteFile(file.id)">Delete</button>
      </li>
    </ul>
  </div>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      file: null,
      files: []
    };
  },
  methods: {
    // Handle file selection
    onFileChange(event) {
      this.file = event.target.files[0];
    },

    // Upload the file
    async uploadFile() {
      const formData = new FormData();
      formData.append("file", this.file);

      try {
        const response = await axios.post("http://localhost:8080/api/files/upload", formData, {
          headers: {
            "Content-Type": "multipart/form-data"
          }
        });
        console.log("File uploaded successfully", response.data);
        this.fetchFiles();  // Refresh the file list
      } catch (error) {
        console.error("File upload failed", error);
      }
    },

    // Fetch all files
    async fetchFiles() {
      try {
        const response = await axios.get("http://localhost:8080/api/files");
        this.files = response.data;
      } catch (error) {
        console.error("Error fetching files", error);
      }
    },

    // Download a file by ID
    async downloadFile(fileId) {
      try {
        const response = await axios.get(`http://localhost:8080/api/files/${fileId}`, {
          responseType: "blob"
        });
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement("a");
        link.href = url;
        link.setAttribute("download", fileId); // You can add file name here
        document.body.appendChild(link);
        link.click();
      } catch (error) {
        console.error("Error downloading file", error);
      }
    },

    // Delete a file by ID
    async deleteFile(fileId) {
      try {
        await axios.delete(`http://localhost:8080/api/files/${fileId}`);
        this.fetchFiles();  // Refresh the file list
      } catch (error) {
        console.error("Error deleting file", error);
      }
    }
  },
  created() {
    this.fetchFiles();  // Fetch files when component is created
  }
};
</script>

<style scoped>
/* Add any styling here */
</style>

2.4 Run the Vue Application

Run your Vue.js application:

npm run serve

It will be available at http://localhost:8081.

Step 3: Test the Application

  1. Upload a file: Choose a file from your local machine and upload it.
  2. List files: The list of uploaded files will appear on the page.
  3. Download a file: Click the "Download" button next to a file to download it.
  4. Delete a file: Click the "Delete" button next to a file to remove it from the server.

Step 4: Conclusion

This guide shows how to create a full-stack application with Vue.js for the frontend and Spring Boot for the backend. You can extend this functionality by adding file size limits, user authentication, error handling, and more.

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