You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot部署AWS Lambda遇HttpMediaTypeNotSupportedException错误求助

问题描述

在AWS Lambda中运行Spring Boot REST应用时,调用函数处理器(无论是RequestHandler<AwsProxyRequest, AwsProxyResponse>还是RequestStreamHandler),在handler.proxy或handler.proxyStream环节持续返回415错误:

Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/octet-stream' is not supported]
c.a.s.p.internal.LambdaContainerHandler  : 127.0.0.1 null- null [11/10/2023:13:05:54Z] "POST /data/firstDataCreatedViaSpringBoot null" 415 - "-" "Custom User Agent String" combined

Spring Boot应用本地运行正常,但通过Lambda处理器接收请求时始终触发媒体类型不支持错误。已尝试在测试事件中添加Content-Type: application/json,并在Controller中添加consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE,甚至通过Lambda函数URL直接调用(未经过API网关),问题依然存在。

解决方案

1. 匹配Lambda调用方式选择对应处理器

SpringBootLambdaContainerHandler.getAwsProxyHandler()是为API Gateway代理请求设计的,它期望输入是AwsProxyRequest格式(包含headers、body等嵌套结构)。但直接使用Lambda函数URL调用时,请求输入是原始JSON体,而非AwsProxyRequest包装结构,这会导致Spring无法识别正确的Content-Type,默认被当作application/octet-stream。

此时应改用getRawHandler()处理原始请求:

public class LambdaHandler implements RequestStreamHandler {

    private static SpringBootLambdaContainerHandler<InputStream, OutputStream> handler;
    static {
        try {
            // 使用RawHandler处理原始请求,而非Api Gateway的Proxy格式
            handler = SpringBootLambdaContainerHandler.getRawHandler(DataDemoApplication.class);
        } catch (ContainerInitializationException e) {
            throw new RuntimeException("Could not initialize Spring Boot application", e);
        }
    }

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        handler.proxyStream(inputStream, outputStream, context);
    }
}

2. 修正Controller的媒体类型配置

移除仅支持application/octet-stream的配置,恢复或添加对application/json的支持,兼容两种请求场景:

@RestController
@RequestMapping(value = "/data", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_OCTET_STREAM_VALUE})
public class DataController {
    // ... 你的接口实现
}

3. 调整Lambda控制台测试事件格式

如果使用Lambda控制台测试函数URL调用,不需要使用AwsProxyRequest格式,直接发送原始JSON体即可:

{"name": "Jarda", "email": "jarda@idc.com"}

同时在测试配置的"Headers"中添加Content-Type: application/json。

4. 手动包装请求(可选)

如果必须使用AwsProxyRequest处理器且直接调用Lambda函数URL,可在处理器中手动将原始请求包装为AwsProxyRequest并设置正确的Content-Type:

@Override
public AwsProxyResponse handleRequest(InputStream inputStream, Context context) throws IOException {
    // 读取原始请求体
    String body = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
    
    // 构造AwsProxyRequest,设置正确的Content-Type
    AwsProxyRequest request = new AwsProxyRequest();
    request.setHttpMethod("POST");
    request.setPath("/data/firstDataCreatedViaSpringBoot");
    request.setBody(body);
    
    Map<String, String> headers = new HashMap<>();
    headers.put("Content-Type", "application/json");
    request.setHeaders(headers);
    
    return handler.proxy(request, context);
}

内容的提问来源于stack exchange,提问作者Radek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 18:22:13