File Upload and Download
Upload resumes, download PDFs. Files made easy.
The Hyderabad Metro Luggage Check Analogy:
When you carry a backpack on the Hyderabad Metro, the security scanner doesn’t look inside your pockets. It scans the whole bag as one unit.
Normal HTTP requests send data as a single JSON body. But when uploading files, the browser sends a “Multipart/Form-Data” request. It splits the HTTP body into different “parts” — one part for the file, one part for the text fields. Spring’s MultipartFile reads these specific parts.
- MultipartFile: An interface representing an uploaded file. It provides methods like
getOriginalFilename(),getBytes(), andtransferTo(). - application.properties: You must configure limits for file sizes to prevent attackers from crashing your server with a 10GB file.
- ResponseEntity<Resource>: The standard way to download a file.
Resourcerepresents the actual file bytes.
# Max file size allowed
spring.servlet.multipart.max-file-size=10MB
# Max total request size allowed
spring.servlet.multipart.max-request-size=10MBpackage com.devinhyderabad;
import org.springframework.web.bind.annotation.*;
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;
@RestController
@RequestMapping("/api/files")
public class FileController {
private static final String UPLOAD_DIR = "uploads/";
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.badRequest().body("File is empty");
}
try {
Path uploadPath = Paths.get(UPLOAD_DIR);
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
Path filePath = uploadPath.resolve(file.getOriginalFilename());
file.transferTo(filePath.toFile());
return ResponseEntity.ok("File uploaded successfully: " + file.getOriginalFilename());
} catch (IOException e) {
return ResponseEntity.internalServerError().body("Failed to upload file");
}
}
} @GetMapping("/download/{filename}")
public ResponseEntity<Resource> downloadFile(@PathVariable String filename) {
try {
Path filePath = Paths.get(UPLOAD_DIR).resolve(filename).normalize();
Resource resource = new UrlResource(filePath.toUri());
if (resource.exists() && resource.isReadable()) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="" + resource.getFilename() + """)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} else {
return ResponseEntity.notFound().build();
}
} catch (IOException e) {
return ResponseEntity.internalServerError().build();
}
}
}Interview Question: “Where should you store uploaded files in an enterprise application?”
Answer: For local development, storing files on the local disk is fine. In production (like AWS/Docker), local disk is ephemeral and gets wiped on restart. Enterprise apps store files in cloud object storage like Amazon S3, Azure Blob Storage, or a database BLOB column.
Enterprise Note: Always sanitize the filename before saving it. file.getOriginalFilename() can include path traversal strings like ../../etc/passwd. Use Paths.get(name).getFileName().toString() to strip directory paths.
Key Takeaways
- ✅ MultipartFile handles file uploads with getOriginalFilename(), getBytes(), transferTo()
- ✅ Always set max file size limits in application.properties to prevent abuse
- ✅ ResponseEntity<Resource> is the standard way to download files
- ✅ Always sanitize filenames to prevent path traversal attacks
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login