In many web applications, file handling is a common requirement — whether it’s uploading profile pictures, downloading reports, or exporting data. Spring Boot makes it easy to build robust REST APIs that support file upload and download using standard HTTP protocols.
In this guide, we’ll build:
- A REST API to upload files using
MultipartFile
- A REST API to download files from the server
- Simple validations and content-type handling

⚙️ Project Setup
Dependencies:
1 2 3 4 5 6 7 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> |
📁 Directory Structure:
1 2 3 4 5 6 7 8 |
src/main/java └── com.kscodes.fileapi ├── controller ├── service └── model |
⬆️ File Upload REST API
✅ Create Upload Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@RestController @RequestMapping("/api/files") public class FileUploadController { private final String uploadDir = "uploads/"; @PostMapping("/upload") public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) { try { Path path = Paths.get(uploadDir + file.getOriginalFilename()); Files.createDirectories(path.getParent()); Files.write(path, file.getBytes()); return ResponseEntity.ok("File uploaded successfully: " + file.getOriginalFilename()); } catch (IOException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("Failed to upload file"); } } } |
🔒 Add Validation (Optional)
1 2 3 4 5 6 7 8 9 10 |
if (file.isEmpty()) { return ResponseEntity.badRequest().body("File is empty"); } if (!file.getContentType().equals("application/pdf")) { return ResponseEntity.badRequest().body("Only PDF files are allowed"); } |
⬇️ File Download REST API
✅ Add Download Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@GetMapping("/download/{filename}") public ResponseEntity<Resource> downloadFile(@PathVariable String filename) { try { Path path = Paths.get(uploadDir + filename); Resource resource = new UrlResource(path.toUri()); if (resource.exists()) { String contentType = Files.probeContentType(path); return ResponseEntity.ok() .contentType(MediaType.parseMediaType(contentType)) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"") .body(resource); } else { return ResponseEntity.notFound().build(); } } catch (IOException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } |
🧪 Testing the APIs
✅ Upload File using Postman
- Method:
POST
- URL:
http://localhost:8080/api/files/upload
- Body: Form-data with key
file
and attach any file
✅ Download File
- Method:
GET
- URL:
http://localhost:8080/api/files/download/filename.txt
- Response: Prompts file download
🧠 Best Practices
Best Practice | Description |
---|---|
✅ Limit file size | Configure spring.servlet.multipart.max-file-size=5MB |
✅ Sanitize filename | Prevent path traversal with filename.replaceAll("[^a-zA-Z0-9\\.\\-]", "_") |
✅ Store in DB or Cloud | For large-scale apps, consider storing file metadata in a DB and files in cloud (e.g., S3) |
✅ Secure endpoints | Protect upload/download routes using Spring Security |
✅ Return custom responses | Use custom DTOs for better client experience |
⚙️ Optional: application.properties
1 2 3 4 5 |
spring.servlet.multipart.max-file-size=5MB spring.servlet.multipart.max-request-size=5MB |
📁 Upload Directory Setup (Optional)
Ensure the directory exists or create one programmatically:
1 2 3 4 5 6 7 |
@PostConstruct public void init() { new File("uploads").mkdirs(); } |
✅ Conclusion
Handling file upload and download in Spring Boot is simple with MultipartFile
and ResponseEntity
. With proper error handling, validation, and security, you can build production-ready APIs for file management quickly.