Spring Boot
MultipartFile
@RequestParam
File Upload
Java Development

Using RequestParam for multipartfile is a right way?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Yes, using @RequestParam for MultipartFile is the standard and correct approach in Spring Boot for handling file uploads. The annotation binds a multipart form field to a MultipartFile parameter in your controller method. For more complex scenarios with additional metadata, use @RequestPart instead. Both annotations work with multipart/form-data requests and are fully supported by Spring's multipart resolver.

Basic File Upload with @RequestParam

java
1@RestController
2@RequestMapping("/api/files")
3public class FileUploadController {
4
5    @PostMapping("/upload")
6    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
7        if (file.isEmpty()) {
8            return ResponseEntity.badRequest().body("File is empty");
9        }
10
11        String filename = file.getOriginalFilename();
12        long size = file.getSize();
13        String contentType = file.getContentType();
14
15        // Save to disk
16        Path destination = Path.of("/uploads", filename);
17        file.transferTo(destination);
18
19        return ResponseEntity.ok("Uploaded: " + filename + " (" + size + " bytes)");
20    }
21}

The client sends a multipart/form-data request with a form field named "file".

cURL Test

bash
curl -X POST http://localhost:8080/api/files/upload \
  -F "file=@/path/to/document.pdf"

Multiple File Upload

java
1@PostMapping("/upload-multiple")
2public ResponseEntity<String> uploadMultiple(
3        @RequestParam("files") List<MultipartFile> files) {
4
5    for (MultipartFile file : files) {
6        if (!file.isEmpty()) {
7            file.transferTo(Path.of("/uploads", file.getOriginalFilename()));
8        }
9    }
10
11    return ResponseEntity.ok("Uploaded " + files.size() + " files");
12}
bash
curl -X POST http://localhost:8080/api/files/upload-multiple \
  -F "[email protected]" \
  -F "[email protected]"

File Upload with Additional Form Data

java
1@PostMapping("/upload-with-metadata")
2public ResponseEntity<String> uploadWithMetadata(
3        @RequestParam("file") MultipartFile file,
4        @RequestParam("description") String description,
5        @RequestParam(value = "category", defaultValue = "general") String category) {
6
7    // file, description, and category are all extracted from the multipart form
8    return ResponseEntity.ok(
9        "File: " + file.getOriginalFilename() +
10        ", Description: " + description +
11        ", Category: " + category
12    );
13}
bash
1curl -X POST http://localhost:8080/api/files/upload-with-metadata \
2  -F "[email protected]" \
3  -F "description=Annual report" \
4  -F "category=reports"

@RequestParam vs @RequestPart

java
1// @RequestParam: simple file + string fields
2@PostMapping("/simple")
3public void simple(
4    @RequestParam("file") MultipartFile file,
5    @RequestParam("name") String name) { }
6
7// @RequestPart: file + JSON body parts (with content type)
8@PostMapping("/complex")
9public void complex(
10    @RequestPart("file") MultipartFile file,
11    @RequestPart("metadata") FileMetadata metadata) { }
12// FileMetadata is deserialized from JSON automatically

@RequestPart uses the Content-Type header of each part for deserialization. Use it when sending JSON alongside files:

bash
curl -X POST http://localhost:8080/api/files/complex \
  -F "[email protected]" \
  -F "metadata={\"title\":\"Report\",\"year\":2025};type=application/json"

File Size Configuration

yaml
1# application.yml
2spring:
3  servlet:
4    multipart:
5      max-file-size: 10MB          # Max single file size
6      max-request-size: 50MB       # Max total request size
7      enabled: true                 # Enable multipart (default: true)
8      file-size-threshold: 2KB     # Threshold to write to disk vs memory
properties
# application.properties
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=50MB

File Validation

java
1@PostMapping("/upload")
2public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file) {
3    // Check file is not empty
4    if (file.isEmpty()) {
5        return ResponseEntity.badRequest().body("File is empty");
6    }
7
8    // Validate file size (programmatic check)
9    if (file.getSize() > 5 * 1024 * 1024) {  // 5MB
10        return ResponseEntity.badRequest().body("File too large");
11    }
12
13    // Validate content type
14    String contentType = file.getContentType();
15    List<String> allowedTypes = List.of("image/jpeg", "image/png", "application/pdf");
16    if (!allowedTypes.contains(contentType)) {
17        return ResponseEntity.badRequest().body("Invalid file type: " + contentType);
18    }
19
20    // Validate file extension
21    String filename = file.getOriginalFilename();
22    if (filename != null && !filename.matches(".*\\.(jpg|jpeg|png|pdf)$")) {
23        return ResponseEntity.badRequest().body("Invalid file extension");
24    }
25
26    file.transferTo(Path.of("/uploads", filename));
27    return ResponseEntity.ok("Uploaded successfully");
28}

Saving to Different Locations

java
1// Save to disk
2file.transferTo(Path.of("/uploads", file.getOriginalFilename()));
3
4// Read as byte array (for database storage)
5byte[] bytes = file.getBytes();
6
7// Read as InputStream (for streaming to cloud storage)
8try (InputStream inputStream = file.getInputStream()) {
9    // Upload to S3, GCS, Azure Blob, etc.
10    s3Client.putObject(bucket, key, inputStream, metadata);
11}

Exception Handling

java
1@ControllerAdvice
2public class FileUploadExceptionHandler {
3
4    @ExceptionHandler(MaxUploadSizeExceededException.class)
5    public ResponseEntity<String> handleMaxSizeException(MaxUploadSizeExceededException ex) {
6        return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE)
7            .body("File size exceeds the maximum allowed size");
8    }
9
10    @ExceptionHandler(MultipartException.class)
11    public ResponseEntity<String> handleMultipartException(MultipartException ex) {
12        return ResponseEntity.badRequest()
13            .body("Invalid multipart request: " + ex.getMessage());
14    }
15}

Common Pitfalls

  • Missing multipart/form-data content type: The client must send the request with Content-Type: multipart/form-data. Sending JSON with a file field does not work — the file must be a multipart form part. Most HTTP clients (Postman, cURL with -F) set this automatically.
  • Parameter name mismatch: @RequestParam("file") must match the form field name exactly. If the client sends [email protected] but the annotation says @RequestParam("document"), Spring returns a 400 error with "Required request part 'document' is not present".
  • File size limit exceeded silently: The default max-file-size is 1MB. Large uploads fail with a MaxUploadSizeExceededException. Configure spring.servlet.multipart.max-file-size and max-request-size in application properties.
  • Using @RequestBody instead of @RequestParam: @RequestBody reads the entire request body as a single object (for JSON). For file uploads, use @RequestParam or @RequestPart. Using @RequestBody with MultipartFile causes a "Content type not supported" error.
  • Not sanitizing file names: file.getOriginalFilename() returns the client-provided filename, which may contain path traversal characters like ../. Always sanitize the filename before saving: Paths.get(filename).getFileName().toString().

Summary

  • @RequestParam("file") MultipartFile file is the standard approach for file uploads in Spring Boot
  • Use @RequestPart when combining files with JSON metadata in the same request
  • Configure max-file-size and max-request-size in application properties for large uploads
  • Validate file size, content type, and file extension before processing
  • Always sanitize getOriginalFilename() to prevent path traversal attacks
  • Handle MaxUploadSizeExceededException with a @ControllerAdvice for user-friendly error messages

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.