Prerequisites
Before we start, ensure you have the following:
- Java Development Kit (JDK) installed
- Apache Maven installed
- Node.js and npm installed
- An IDE (such as IntelliJ IDEA, Eclipse, or VS Code) installed
Step 1: Setting Up the Spring Boot Project
1.1 Create a Spring Boot Project
-
Open Spring Initializr:
- Go to Spring Initializr in your web browser.
-
Configure Project Metadata:
- Project: Maven Project
- Language: Java
- Spring Boot: Select the latest version of Spring Boot 3
- Group: com.example
- Artifact: file-upload-download
- Name: file-upload-download
- Description: File Upload and Download Application with Spring Boot and Vue.js
- Package Name: com.example.fileuploaddownload
- Packaging: Jar
- Java Version: 17 (or your preferred version)
- Click
Next
.
-
Select Dependencies:
- On the
Dependencies
screen, select the dependencies you need:- Spring Web
- Spring Boot DevTools
- Click
Next
.
- On the
-
Generate the Project:
- Click
Generate
to download the project zip file. - Extract the zip file to your desired location.
- Click
-
Open the Project in Your IDE:
- Open your IDE and import the project as a Maven project.
1.2 Update application.properties
Open the application.properties
file located in the src/main/resources
directory and add the following configuration:
# File storage location
file.upload-dir=uploads
1.3 Create a File Storage Service
In the com.example.fileuploaddownload.service
package, create a new Java class named FileStorageService
:
package com.example.fileuploaddownload.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
@Service
public class FileStorageService {
private final Path fileStorageLocation;
public FileStorageService(@Value("${file.upload-dir}") String uploadDir) {
this.fileStorageLocation = Paths.get(uploadDir)
.toAbsolutePath().normalize();
try {
Files.createDirectories(this.fileStorageLocation);
} catch (Exception ex) {
throw new RuntimeException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
public String storeFile(MultipartFile file) {
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
if (fileName.contains("..")) {
throw new RuntimeException("Invalid path sequence " + fileName);
}
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
throw new RuntimeException("Could not store file " + fileName + ". Please try again!", ex);
}
}
public Path loadFileAsResource(String fileName) {
return this.fileStorageLocation.resolve(fileName).normalize();
}
}
1.4 Create the FileController
Class
In the com.example.fileuploaddownload.controller
package, create a new Java class named FileController
:
package com.example.fileuploaddownload.controller;
import com.example.fileuploaddownload.service.FileStorageService;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
@RestController
@RequestMapping("/api/files")
public class FileController {
private final FileStorageService fileStorageService;
public FileController(FileStorageService fileStorageService) {
this.fileStorageService = fileStorageService;
}
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
return fileStorageService.storeFile(file);
}
@GetMapping("/download/{fileName:.+}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
Path filePath = fileStorageService.loadFileAsResource(fileName);
Resource resource;
try {
resource = new UrlResource(filePath.toUri());
if (!resource.exists()) {
throw new RuntimeException("File not found " + fileName);
}
} catch (Exception e) {
throw new RuntimeException("File not found " + fileName, e);
}
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
Step 2: Creating the Frontend with Vue.js
2.1 Set Up Vue Project
-
Open a terminal and navigate to your workspace directory.
-
Create a new Vue project using Vue CLI:
npm install -g @vue/cli vue create vue-frontend
-
Navigate to the project directory:
cd vue-frontend
2.2 Install Axios and Bootstrap
Install Axios to make HTTP requests and Bootstrap for styling:
npm install axios bootstrap
2.3 Create Components
Create the necessary components for file upload and download.
2.3.1 Create FileService.js
Create a new file FileService.js
in the src
directory to handle API requests for file upload and download:
import axios from 'axios';
const API_BASE_URL = "http://localhost:8080/api/files";
class FileService {
uploadFile(file) {
let formData = new FormData();
formData.append("file", file);
return axios.post(`${API_BASE_URL}/upload`, formData, {
headers: {
"Content-Type": "multipart/form-data"
}
});
}
downloadFile(fileName) {
return axios.get(`${API_BASE_URL}/download/${fileName}`, {
responseType: 'blob'
});
}
}
export default new FileService();
2.3.2 Create UploadComponent.vue
Create a new file UploadComponent.vue
in the src/components
directory:
<template>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">Upload File</div>
<div class="card-body">
<form @submit.prevent="uploadFile">
<div class="form-group">
<input type="file" @change="selectFile" class="form-control" />
</div>
<button type="submit" class="btn btn-primary mt-3">Upload</button>
</form>
<div v-if="fileName" class="mt-3">
<span>Uploaded file: {{ fileName }}</span>
<button @click="downloadFile" class="btn btn-secondary ml-3">Download</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import FileService from '../FileService';
export default {
data() {
return {
selectedFile: null,
fileName: ''
};
},
methods: {
selectFile(event) {
this.selectedFile = event.target.files[0];
},
uploadFile() {
FileService.uploadFile(this.selectedFile).then(response => {
this.fileName = response.data;
});
},
downloadFile() {
FileService.downloadFile(this.fileName).then(response => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', this.fileName);
document.body.appendChild(link);
link.click();
});
}
}
};
</script>
2.3.3 Create App.vue
Modify the App.vue
file to include the UploadComponent
:
<template>
<div id="app">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">File Upload and Download</a>
</nav>
<upload-component></upload-component>
</div>
</template>
<script>
import UploadComponent from './components/UploadComponent.vue';
export default {
name: 'App',
components: {
UploadComponent
}
};
</script>
<style>
nav {
margin-bottom: 20px;
}
</style>
2.3.4 Update main.js
Ensure the main.js
file is set up correctly:
import { createApp } from 'vue';
import App
from './App.vue';
import 'bootstrap/dist/css/bootstrap.min.css';
createApp(App).mount('#app');
Step 3: Running the Application
3.1 Run the Spring Boot Application
- Open the
FileUploadDownloadApplication
class in thesrc/main/java/com/example/fileuploaddownload
directory. - Click the green
Run
button in your IDE or use the terminal to run the application:./mvnw spring-boot:run
3.2 Run the Vue.js Application
-
Open a terminal and navigate to the
vue-frontend
directory. -
Start the Vue application:
npm run serve
-
Open your web browser and navigate to
http://localhost:8080
.
You should now be able to upload and download files using the Vue.js frontend and Spring Boot backend.
Conclusion
In this tutorial, we created a full-stack application using Spring Boot for the backend and Vue.js for the frontend. We implemented file upload and download functionalities and handled the necessary configurations to connect the two parts of the application. This setup provides a solid foundation for developing more complex full-stack applications.
Comments
Post a Comment
Leave Comment