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

Aperta
#1,516 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
42/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
aws, java, spring-boot
Ambito
api, backend, cloud

Direzione di ricerca

Inizia con la configurazione mostrata di LambdaHandler e StageAwareAwsProxyHttpServletRequestReader, quindi traccia come aws-serverless-java-container-springboot3 passa la richiesta multipart e il tipo di contenuto image/jpeg a Spring Boot. Riproduci l'upload tramite API Gateway/Lambda e verifica che il controller associ l'immagine a MultipartFile senza restituire un errore 415.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.

Lingua principale
Java
Stelle
1.6k
Fork
575
Merge medio
1g 15h
PR unite (30g)
12

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di aws/serverless-java-container

Tutte le issue di aws/serverless-java-container

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.