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: spring-boot-react-file-upload
- Name: spring-boot-react-file-upload
- Description: Full Stack Application with Spring Boot and React for File Upload
- Package Name: com.example.springbootreactfileupload
- 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 Project Structure
After importing the project, you will see the following structure in your IDE:
spring-boot-react-file-upload
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── springbootreactfileupload
│ │ │ ├── SpringBootReactFileUploadApplication.java
│ │ │ ├── controller
│ │ │ └── service
│ ├── main
│ │ └── resources
│ │ ├── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── springbootreactfileupload
│ └── SpringBootReactFileUploadApplicationTests.java
└── pom.xml
Step 2: Creating the Backend
2.1 Create the File Upload Service
This service will handle storing the uploaded files on the server.
In the service
package, create a new Java class named FileStorageService
:
package com.example.springbootreactfileupload.service;
import org.springframework.stereotype.Service;
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.util.UUID;
@Service
public class FileStorageService {
private final Path fileStorageLocation = Paths.get("uploads").toAbsolutePath().normalize();
public FileStorageService() {
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) {
// Normalize file name
String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
try {
// Copy file to the target location (Replacing existing file with the same name)
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation);
return fileName;
} catch (IOException ex) {
throw new RuntimeException("Could not store file " + fileName + ". Please try again!", ex);
}
}
}
Explanation:
- Path Initialization: The
fileStorageLocation
is initialized to the "uploads" directory in the project root. This is where the files will be stored. - Directory Creation: In the constructor, we create the "uploads" directory if it doesn't exist.
- File Storage Method: The
storeFile
method stores the uploaded file with a unique name by appending a UUID to avoid conflicts. It then saves the file in thefileStorageLocation
directory.
2.2 Create the File Upload Controller
This controller will expose the REST API endpoint to handle file uploads.
In the controller
package, create a new Java class named FileUploadController
:
package com.example.springbootreactfileupload.controller;
import com.example.springbootreactfileupload.service.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/api/files")
public class FileUploadController {
private final FileStorageService fileStorageService;
@Autowired
public FileUploadController(FileStorageService fileStorageService) {
this.fileStorageService = fileStorageService;
}
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
String fileName = fileStorageService.storeFile(file);
return ResponseEntity.ok("File uploaded successfully: " + fileName);
}
}
Explanation:
- File Upload Endpoint: The
/upload
endpoint handlesPOST
requests to upload files. It receives aMultipartFile
and stores it using theFileStorageService
. - Response: It returns a success message with the stored file name.
2.3 Update application.properties
Ensure the application.properties
file is set up correctly to handle file uploads:
# File upload properties
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=2MB
Step 3: Creating the Frontend with React
3.1 Set Up React Project
-
Open a terminal and navigate to your workspace directory.
-
Create a new React project using Create React App:
npx create-react-app react-frontend
-
Navigate to the project directory:
cd react-frontend
3.2 Install Axios
Install Axios to make HTTP requests:
npm install axios
3.3 Install Bootstrap
Install Bootstrap for styling:
npm install bootstrap
3.4 Create Components
Create the necessary components for the file upload functionality.
3.4.1 Create FileUploadService.js
Create a new file FileUploadService.js
in the src
directory to handle API requests:
import axios from 'axios';
const API_BASE_URL = "http://localhost:8080/api/files";
class FileUploadService {
uploadFile(file) {
const formData = new FormData();
formData.append("file", file);
return axios.post(`${API_BASE_URL}/upload`, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
}
}
export default new FileUploadService();
Explanation:
- API Base URL: The base URL for the API endpoints.
- uploadFile Method: This method takes a file as input, creates a
FormData
object, and sends aPOST
request to the backend API to upload the file.
3.4.2 Create FileUploadComponent.js
Create a new file FileUploadComponent.js
in the src/components
directory:
import React, { useState } from 'react';
import FileUploadService from '../FileUploadService';
import 'bootstrap/dist/css/bootstrap.min.css';
const FileUploadComponent = () => {
const [selectedFile, setSelectedFile] = useState(null);
const [message, setMessage] = useState('');
const handleFileChange = (e) => {
setSelectedFile(e.target.files[0]);
};
const handleFileUpload = async (e) => {
e.preventDefault();
try {
const response = await FileUploadService.uploadFile(selectedFile);
setMessage(response.data);
} catch (error) {
setMessage('File upload failed!');
}
};
return (
<div className="container mt-5">
<div className="row justify-content-center">
<div className="col-md-6">
<div className="card">
<div className="card-header">File Upload</div>
<div className="card-body">
{message && <div className="alert alert-info">{message}</div>}
<form onSubmit={handleFileUpload}>
<div className="form-group">
<label>Choose file</label>
<input
type="file"
className="form-control"
onChange={handleFileChange}
/>
</div>
<button
type="submit" className="btn btn-primary mt-3">Upload</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
};
export default FileUploadComponent;
Explanation:
- File Selection: The
handleFileChange
method sets the selected file to the component's state when a file is chosen. - File Upload: The
handleFileUpload
method sends the selected file to the backend API usingFileUploadService
and handles the response or error messages. - UI: The component renders a form with a file input and a submit button. It displays messages based on the file upload result.
3.4.3 Create App.js
Modify the App.js
file to include the file upload component:
import React from 'react';
import FileUploadComponent from './components/FileUploadComponent';
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
return (
<div className="container">
<FileUploadComponent />
</div>
);
};
export default App;
3.4.4 Update index.js
Ensure the index.js
file is set up correctly:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Step 4: Running the Application
4.1 Run the Spring Boot Application
- Open the
SpringBootReactFileUploadApplication
class in thesrc/main/java/com/example/springbootreactfileupload
directory. - Click the green
Run
button in your IDE or use the terminal to run the application:./mvnw spring-boot:run
4.2 Run the React Application
-
Open a terminal and navigate to the
react-frontend
directory. -
Start the React application:
npm start
-
Open your web browser and navigate to
http://localhost:3000
.
You can now use the file upload functionality provided by the React frontend and Spring Boot backend.
Conclusion
In this tutorial, we created a full-stack application using Spring Boot for the backend and React (with functional components and hooks) for the frontend. We implemented a file upload functionality and created a simple file upload form with React. This setup provides a solid foundation for developing more complex full-stack applications with file upload capabilities.
Comments
Post a Comment
Leave Comment