If your plan for file uploads is to toss files at the server and hope for the best you are in the wrong place. This guide walks through a RESTful Spring Boot multipart file upload endpoint that behaves itself. We accept a MultipartFile in a controller, hand it to a storage service, set multipart limits, add sane error handling, and test with curl or Postman. No rituals required.
Keep the controller minimal. Validate the upload and return a created response with a Location header. The controller below delegates storage to a service and returns a small JSON payload with the filename.
@RestController
@RequestMapping("/api")
public class FileUploadController {
private final StorageService storageService;
public FileUploadController(StorageService storageService) {
this.storageService = storageService;
}
@PostMapping("/upload")
public ResponseEntity> uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
if (file.isEmpty()) {
return ResponseEntity.badRequest().body("No file uploaded");
}
String filename = storageService.store(file);
URI location = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/files/")
.path(filename)
.build()
.toUri();
return ResponseEntity.created(location).body(Collections.singletonMap("filename", filename));
}
}
Separate storage logic from the controller. This example writes to disk and generates a UUID based filename to avoid collisions.
public interface StorageService {
String store(MultipartFile file) throws IOException;
}
public class FileSystemStorageService implements StorageService {
private final Path root = Paths.get("uploads");
public FileSystemStorageService() throws IOException {
Files.createDirectories(root);
}
@Override
public String store(MultipartFile file) throws IOException {
String ext = StringUtils.getFilenameExtension(file.getOriginalFilename());
String filename = UUID.randomUUID().toString() + (ext != null ? "." + ext : "");
Path target = root.resolve(filename);
try (InputStream in = file.getInputStream()) {
Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
}
return filename;
}
}
Set sensible defaults in application.properties so you do not get surprised by 500 errors when someone uploads a 500 MB video because they "forgot" the rules.
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
Translate exceptions into helpful HTTP responses. For example handle MaxUploadSizeExceededException and return 413 Payload Too Large. Your users will appreciate the hint and your logs will be less dramatic.
@ControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity> handleMaxUpload(MaxUploadSizeExceededException ex) {
return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE)
.body("File too large");
}
}
Use curl for scripting and Postman for manual checks. Make sure the request is multipart form data and inspect the response codes and headers.
curl -v -F "file=@/path/to/image.jpg" http://localhost:8080/api/upload
Follow these steps and you will have a predictable RESTful Spring file upload endpoint. If it still breaks you can blame the network gremlins and then read the logs like a responsible adult.
I know how you can get Azure Certified, Google Cloud Certified and AWS Certified. It's a cool certification exam simulator site called certificationexams.pro. Check it out, and tell them Cameron sent ya!
This is a dedicated watch page for a single video.