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

AWS Serverless Spring Boot本地部署失败,请求技术支持

解决AWS Serverless Spring Boot本地调用Lambda时的Servlet类缺失问题

我之前在搭建AWS Serverless Spring Boot项目时也碰到过一模一样的问题,这个javax/servlet/ServletContainerInitializer缺失的异常,本质是依赖配置不完整或者版本兼容问题,结合你的代码和场景,我给你几个可行的解决步骤:


1. 修正依赖配置(核心解决点)

这个异常90%的概率是因为你没有正确配置Servlet相关依赖,或者Spring Boot的Web starter和AWS Lambda容器的适配有问题。下面给出Maven和Gradle的标准配置:

Maven pom.xml 片段

<dependencies>
    <!-- Spring Boot Web 核心依赖,排除默认Tomcat容器(Lambda不需要) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- AWS Serverless Java容器适配包(务必和Spring Boot版本匹配) -->
    <!-- 如果你用Spring Boot 2.x,用这个: -->
    <dependency>
        <groupId>com.amazonaws.serverless</groupId>
        <artifactId>aws-serverless-java-container-springboot</artifactId>
        <version>2.0.2</version>
    </dependency>
    <!-- 如果你用Spring Boot 3.x,替换成这个: -->
    <!-- <dependency>
        <groupId>com.amazonaws.serverless</groupId>
        <artifactId>aws-serverless-java-container-springboot3</artifactId>
        <version>3.0.1</version>
    </dependency> -->

    <!-- 本地运行必须的Servlet API依赖 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- AWS Lambda核心依赖 -->
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-core</artifactId>
        <version>1.2.21</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Gradle build.gradle 片段

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    // 排除Tomcat容器
    implementation('org.springframework.boot:spring-boot-starter-web') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
    }
    // 适配包(根据Spring Boot版本选择)
    implementation 'com.amazonaws.serverless:aws-serverless-java-container-springboot:2.0.2'
    // Spring Boot 3.x用:implementation 'com.amazonaws.serverless:aws-serverless-java-container-springboot3:3.0.1'
    
    providedRuntime 'javax.servlet:javax.servlet-api:4.0.1'
    providedRuntime 'com.amazonaws:aws-lambda-java-core:1.2.21'
}

2. 简化并优化代码

你的代码可以做一些简化,避免不必要的配置和潜在问题:

优化Application类

@SpringBootApplication已经包含了组件扫描的功能,除非你的Controller不在当前包或子包下,否则不需要额外指定@ComponentScan:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

优化LambdaHandler类

用静态初始化块加载Spring容器,避免每次Lambda调用都重复初始化,同时使用容器自带的流处理方法,减少自定义ObjectMapper的冲突:

import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class LambdaHandler implements RequestStreamHandler {
    private static final Logger log = LoggerFactory.getLogger(LambdaHandler.class);
    // 静态初始化,仅加载一次Spring容器
    private static final SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;

    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
            // 可选:自定义ObjectMapper配置
            // handler.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        } catch (Exception e) {
            log.error("Failed to initialize Spring Boot Lambda handler", e);
            throw new RuntimeException("Could not initialize handler", e);
        }
    }

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        // 使用容器自带的流处理方法,避免手动序列化/反序列化的问题
        handler.proxyStream(inputStream, outputStream, context);
        outputStream.flush();
        outputStream.close();
    }
}

3. 本地调用前的必要操作

在执行serverless invoke local -f hello之前,务必完成以下步骤:

  • 执行mvn clean package(Maven)或gradle build(Gradle),确保生成包含所有依赖的可执行JAR
  • 检查serverless.yml中的handler路径是否正确指向你的LambdaHandler类(比如com.your.package.LambdaHandler)

4. 其他排查方向

如果以上步骤还不能解决问题,可以检查:

  • 确认你的Spring Boot版本和AWS Serverless容器适配包的版本兼容(比如Spring Boot 2.x对应aws-serverless-java-container-springboot,3.x对应springboot3后缀的包)
  • 本地环境的JDK版本是否和Lambda配置的Runtime一致(比如Lambda用Java 11,本地也用Java 11)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:05:43