개발기술/Web Dev
Static File Upload
bsh6226
2025. 4. 12. 17:47
Generalized Static File Upload Workflow
Client uploads a file (MultipartFile)
- Client (frontend or mobile) sends a multipart/form-data request:
POST /upload
Content-Type: multipart/form-data
--boundary
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
(binary data)
Server stores the file (locally or in cloud) and returns a public-accessible URL
@PostMapping("/upload")
public String uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
String filename = UUID.randomUUID() + "_" + file.getOriginalFilename();
Path uploadPath = Paths.get("uploads").resolve(filename);
Files.copy(file.getInputStream(), uploadPath);
return "/images/" + filename; // ← URL that client can later use
}
Client sends another API request with resource URL
POST /createPost
{
"title": "Trip to Busan",
"imageUrl": "/images/abc123_image.jpg"
}
Client references the file via URL in future requests
Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/images/**")
.addResourceLocations("file:uploads/"); // ← absolute or relative path
}
}
Two Common Approaches to Static File Uploading
🔁 1. Server-side Uploading (Traditional)
Client → Web Server → Storage Server (e.g., S3, File Server)
- Client uploads the file to your web backend
- Web server saves the file to disk or forwards it to a storage server/cloud
- Then it returns the URL to the client
✅ Pros:
- Easy to control/validate file content
- Centralized logging, security
❌ Cons:
- Web server handles heavy I/O load
- Not scalable for large files or high frequency
⚡ 2. Client-side Direct Uploading (Modern)
Client → Storage Server (e.g., S3, CDN)
→ Then Client → Web Server (with the URL)
- Web server gives the client a "pre-signed URL" or upload destination
- Client directly uploads the file to S3, Google Cloud, or file server
- Then client tells the web server:
"Hey! Here's the file URL I just uploaded"
✅ Pros:
- Offloads storage I/O burden from web server
- Ideal for large files or many users
- Faster user experience
❌ Cons:
- Slightly more complex (requires pre-signed URL logic or CORS config)
- Must trust client-uploaded URLs (validate origin!)
orphaned file
Client uploads a file (e.g., image) → gets the URL
❌ But fails to send the URL to your backend (e.g., due to network error, user cancel, crash)
Result?
- File is stored in your cloud (e.g., S3)
- But the backend never knows about it
- You now have an orphaned file sitting there, unused and untracked
Common Solutions
1. Use Pre-signed URLs with Expiry
- You generate a temporary upload URL (e.g., valid for 5 minutes)
- If the client doesn’t register the URL in time, the uploaded file:
- May expire from a special temp bucket
- Or gets marked for cleanup
2. Delayed file finalization
- Uploads go to a temporary location
- Only upon successful registration (second request), move file to "final" location
- This way, only registered files are made persistent or public
3. Backend cleanup jobs (or lifecycle rules)
- Periodically run a scheduled job or use S3 lifecycle rules:
- Delete files older than X minutes that are not referenced in DB
- You may tag files with pending=true and remove those that never got confirmed