Skip to content

[BUG] MultipartFile mapping issue with Spring Boot 3 and binary media types #1516

@Sathishsharma729

Description

@Sathishsharma729

Description:

I am encountering an issue when trying to upload images from my client to a Spring Boot 3 application deployed as a Lambda function using aws-serverless-java-container-springboot3.

Problem:

Despite configuring API Gateway with multipart/form-data as a binary media type, and observing the binary data successfully reaching the Lambda handler, the Spring controller fails to map the incoming request to a MultipartFile argument. Instead, a GlobalException is triggered with the message:

415 UNSUPPORTED_MEDIA_TYPE "Content type 'image/jpeg' not supported for bodyType=org.springframework.web.multipart.MultipartFile"

Setup:

Framework: Spring Boot 3

Serverless Java Container Dependency:

<dependency>
    <groupId>com.amazonaws.serverless</groupId>
    <artifactId>aws-serverless-java-container-springboot3</artifactId>
    <version>2.1.4</version>
</dependency>

LambdaHandler:

package net.myApp.lambda.handler;

import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.AsyncInitializationWrapper;
import com.amazonaws.serverless.proxy.AwsProxyExceptionHandler;
import com.amazonaws.serverless.proxy.AwsProxySecurityContextWriter;
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletResponseWriter;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
import com.amazonaws.serverless.proxy.spring.SpringBootProxyHandlerBuilder;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import jakarta.ws.rs.core.MediaType;
import net.myApp.lambda.StageAwareAwsProxyHttpServletRequestReader;
import net.myApp.rest.MyApp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class LambdaHandler implements RequestStreamHandler {
  private static final Logger logger = LoggerFactory.getLogger(LambdaHandler.class);
  private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;

  static {
    try {
      handler =
          new SpringBootProxyHandlerBuilder<AwsProxyRequest>()
              .initializationWrapper(new AsyncInitializationWrapper())
              .requestReader(new StageAwareAwsProxyHttpServletRequestReader())
              .responseWriter(new AwsProxyHttpServletResponseWriter())
              .securityContextWriter(new AwsProxySecurityContextWriter())
              .exceptionHandler(new AwsProxyExceptionHandler())
              .requestTypeClass(AwsProxyRequest.class)
              .responseTypeClass(AwsProxyResponse.class)
              .springBootApplication(MyApp.class)
              .buildAndInitialize();
      handler.getContainerConfig().addBinaryContentTypes(MediaType.MULTIPART_FORM_DATA, "image/jpeg", "image/png", "image/jpg");
    } catch (ContainerInitializationException e) {
      logger.error("FATAL: Failed to initialize Spring Boot application container. This will cause cold starts.", e);
      throw new RuntimeException("Could not initialize Spring Boot application", e);
    }
  }

  @Override
  public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
    try {
      handler.proxyStream(input, output, context);
    } catch (Exception ex) {
      logger.error("Error processing Lambda request: {}", ex.getMessage());
      throw ex;
    }
  }
}

API Gateway Configuration: multipart/form-data has been added to the "Binary Media Types" in the API Gateway settings.

Steps Taken (and observations):

Client-side upload: Attempting to upload an image/jpeg file from the client.

API Gateway: Configured multipart/form-data as a binary media type.

Lambda Handler: Logs within the Lambda handler confirm that the binary data is indeed present and being received by the Lambda function.

Spring Controller: The request does not successfully map to a MultipartFile parameter in my Spring controller. Error: The GlobalException handler in my Spring application catches a 415 UNSUPPORTED_MEDIA_TYPE error, specifically stating that image/jpeg is not supported for MultipartFile.

Expected Behavior:

The aws-serverless-java-container should correctly handle the multipart/form-data request, allowing Spring Boot to bind the uploaded file to a MultipartFile object in the controller method.

Actual Behavior:

The request fails with a 415 UNSUPPORTED_MEDIA_TYPE error, indicating that the image/jpeg content type is not being correctly processed for MultipartFile binding within the Spring application, despite the data reaching the Lambda handler as binary.

Possible Cause/Request for Help:

It appears there might be an issue with how aws-serverless-java-container-springboot3 (version 2.1.4) or its underlying dependencies are processing multipart/form-data requests, preventing Spring's MultipartFile resolver from recognizing the incoming binary data as a valid file upload.

Any guidance or a fix for this issue would be greatly appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions