diff --git a/aws-serverless-java-container-springboot2/pom.xml b/aws-serverless-java-container-springboot2/pom.xml
new file mode 100644
index 000000000..f0a8258a3
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/pom.xml
@@ -0,0 +1,171 @@
+
+
+
+ aws-serverless-java-container
+ com.amazonaws.serverless
+ 1.4-SNAPSHOT
+
+ 4.0.0
+
+ com.amazonaws.serverless
+ aws-serverless-java-container-springboot2
+ AWS Serverless Java container support - SpringBoot 2 implementation
+ Allows Java applications written for SpringBoot 2 to run in AWS Lambda
+ https://aws.amazon.com/lambda
+ 1.4-SNAPSHOT
+
+
+ 5.1.9.RELEASE
+ 2.1.8.RELEASE
+
+ 1.8
+ 1.8
+
+
+
+
+
+ com.amazonaws.serverless
+ aws-serverless-java-container-core
+ 1.4-SNAPSHOT
+
+
+
+ org.springframework
+ spring-webflux
+ ${spring.version}
+ true
+
+
+ org.springframework.boot
+ spring-boot
+ ${springboot.version}
+ true
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ ${springboot.version}
+ true
+
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.1
+
+ ${basedir}/target/coverage-reports/jacoco-unit.exec
+ ${basedir}/target/coverage-reports/jacoco-unit.exec
+
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+ jacoco-site
+ package
+
+ report
+
+
+
+ jacoco-check
+ test
+
+ check
+
+
+ true
+
+ BUNDLE
+
+
+ INSTRUCTION
+ COVEREDRATIO
+ ${jacoco.minCoverage}
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.9
+
+ always
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ 3.1.1
+
+
+ Max
+
+ Low
+
+ true
+
+ ${project.build.directory}/spotbugs
+
+
+
+ com.h3xstream.findsecbugs
+ findsecbugs-plugin
+ 1.7.1
+
+
+
+
+
+
+ analyze-compile
+ compile
+
+ check
+
+
+
+
+
+ org.owasp
+ dependency-check-maven
+ ${dependencyCheck.version}
+
+ true
+
+ ${project.basedir}/../owasp-suppression.xml
+
+ 7
+
+
+
+
+ check
+
+
+
+
+
+
+
diff --git a/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/SpringBootLambdaContainerHandler.java b/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/SpringBootLambdaContainerHandler.java
new file mode 100644
index 000000000..c111b2c87
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/SpringBootLambdaContainerHandler.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
+ * with the License. A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+package com.amazonaws.serverless.proxy.spring;
+
+import com.amazonaws.serverless.exceptions.ContainerInitializationException;
+import com.amazonaws.serverless.proxy.*;
+import com.amazonaws.serverless.proxy.internal.servlet.*;
+import com.amazonaws.serverless.proxy.internal.testutils.Timer;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.serverless.proxy.spring.embedded.ServerlessReactiveEmbeddedServerFactory;
+import com.amazonaws.serverless.proxy.spring.embedded.ServerlessServletEmbeddedServerFactory;
+import com.amazonaws.services.lambda.runtime.Context;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.StandardEnvironment;
+
+import javax.servlet.Servlet;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * SpringBoot 1.x implementation of the `LambdaContainerHandler` abstract class. This class uses the `LambdaSpringApplicationInitializer`
+ * object behind the scenes to proxy requests. The default implementation leverages the `AwsProxyHttpServletRequest` and
+ * `AwsHttpServletResponse` implemented in the `aws-serverless-java-container-core` package.
+ *
+ * Important: Make sure to add LambdaFlushResponseListener
in your SpringBootServletInitializer subclass configure().
+ *
+ * @param The incoming event type
+ * @param The expected return type
+ */
+public class SpringBootLambdaContainerHandler extends AwsLambdaServletContainerHandler {
+ private final Class> springBootInitializer;
+ private static final Logger log = LoggerFactory.getLogger(SpringBootLambdaContainerHandler.class);
+ private String[] springProfiles = null;
+
+ private static SpringBootLambdaContainerHandler instance;
+
+ // State vars
+ private boolean initialized;
+
+ /**
+ * We need to rely on the static instance of this for SpringBoot because we need it to access the ServletContext.
+ * Normally, SpringBoot would initialize its own embedded container through the SpringApplication.run()
+ * method. However, in our case we need to rely on the pre-initialized handler and need to fetch information from it
+ * for our mock {@link com.amazonaws.serverless.proxy.spring.embedded.ServerlessReactiveEmbeddedServerFactory}.
+ *
+ * @return The initialized instance
+ */
+ public static SpringBootLambdaContainerHandler getInstance() {
+ return instance;
+ }
+
+ /**
+ * Creates a default SpringLambdaContainerHandler initialized with the `AwsProxyRequest` and `AwsProxyResponse` objects
+ * @param springBootInitializer {@code SpringBootServletInitializer} class
+ * @return An initialized instance of the `SpringLambdaContainerHandler`
+ * @throws ContainerInitializationException If an error occurs while initializing the Spring framework
+ */
+ public static SpringBootLambdaContainerHandler getAwsProxyHandler(Class> springBootInitializer)
+ throws ContainerInitializationException {
+ SpringBootLambdaContainerHandler newHandler = new SpringBootLambdaContainerHandler<>(
+ AwsProxyRequest.class,
+ AwsProxyResponse.class,
+ new AwsProxyHttpServletRequestReader(),
+ new AwsProxyHttpServletResponseWriter(),
+ new AwsProxySecurityContextWriter(),
+ new AwsProxyExceptionHandler(),
+ springBootInitializer);
+ newHandler.initialize();
+ return newHandler;
+ }
+
+ /**
+ * Creates a default SpringLambdaContainerHandler initialized with the `AwsProxyRequest` and `AwsProxyResponse` objects and the given Spring profiles
+ * @param springBootInitializer {@code SpringBootServletInitializer} class
+ * @param profiles A list of Spring profiles to activate
+ * @return An initialized instance of the `SpringLambdaContainerHandler`
+ * @throws ContainerInitializationException If an error occurs while initializing the Spring framework
+ */
+ public static SpringBootLambdaContainerHandler getAwsProxyHandler(Class> springBootInitializer, String... profiles)
+ throws ContainerInitializationException {
+ SpringBootLambdaContainerHandler newHandler = new SpringBootLambdaContainerHandler<>(
+ AwsProxyRequest.class,
+ AwsProxyResponse.class,
+ new AwsProxyHttpServletRequestReader(),
+ new AwsProxyHttpServletResponseWriter(),
+ new AwsProxySecurityContextWriter(),
+ new AwsProxyExceptionHandler(),
+ springBootInitializer);
+ newHandler.activateSpringProfiles(profiles);
+ newHandler.initialize();
+ return newHandler;
+ }
+
+ /**
+ * Creates a new container handler with the given reader and writer objects
+ *
+ * @param requestTypeClass The class for the incoming Lambda event
+ * @param requestReader An implementation of `RequestReader`
+ * @param responseWriter An implementation of `ResponseWriter`
+ * @param securityContextWriter An implementation of `SecurityContextWriter`
+ * @param exceptionHandler An implementation of `ExceptionHandler`
+ * @param springBootInitializer {@code SpringBootServletInitializer} class
+ * @throws ContainerInitializationException If an error occurs while initializing the Spring framework
+ */
+ public SpringBootLambdaContainerHandler(Class requestTypeClass,
+ Class responseTypeClass,
+ RequestReader requestReader,
+ ResponseWriter responseWriter,
+ SecurityContextWriter securityContextWriter,
+ ExceptionHandler exceptionHandler,
+ Class> springBootInitializer)
+ throws ContainerInitializationException {
+ super(requestTypeClass, responseTypeClass, requestReader, responseWriter, securityContextWriter, exceptionHandler);
+ Timer.start("SPRINGBOOT_CONTAINER_HANDLER_CONSTRUCTOR");
+ initialized = false;
+ this.springBootInitializer = springBootInitializer;
+ SpringBootLambdaContainerHandler.setInstance(this);
+
+ Timer.stop("SPRINGBOOT_CONTAINER_HANDLER_CONSTRUCTOR");
+ }
+
+ // this is not pretty. However, because SpringBoot wants to control all of the initialization
+ // we need to access this handler as a singleton from the EmbeddedContainer to set the servlet
+ // context and from the ServletConfigurationSupport implementation
+ private static void setInstance(SpringBootLambdaContainerHandler h) {
+ SpringBootLambdaContainerHandler.instance = h;
+ }
+
+ public void activateSpringProfiles(String... profiles) {
+ springProfiles = profiles;
+ // force a re-initialization
+ initialized = false;
+ }
+
+ @Override
+ protected AwsHttpServletResponse getContainerResponse(AwsProxyHttpServletRequest request, CountDownLatch latch) {
+ return new AwsHttpServletResponse(request, latch);
+ }
+
+ @Override
+ protected void handleRequest(AwsProxyHttpServletRequest containerRequest, AwsHttpServletResponse containerResponse, Context lambdaContext) throws Exception {
+ // this method of the AwsLambdaServletContainerHandler sets the servlet context
+ Timer.start("SPRINGBOOT_HANDLE_REQUEST");
+
+ // wire up the application context on the first invocation
+ if (!initialized) {
+ initialize();
+ }
+
+ containerRequest.setServletContext(getServletContext());
+
+ // process filters & invoke servlet
+ Servlet reqServlet = ((AwsServletContext)getServletContext()).getServletForPath(containerRequest.getPathInfo());
+ doFilter(containerRequest, containerResponse, reqServlet);
+ Timer.stop("SPRINGBOOT_HANDLE_REQUEST");
+ }
+
+
+ @Override
+ public void initialize()
+ throws ContainerInitializationException {
+ Timer.start("SPRINGBOOT_COLD_START");
+
+ SpringApplication app = new SpringApplication(getEmbeddedContainerClasses());
+ if (springProfiles != null && springProfiles.length > 0) {
+ ConfigurableEnvironment springEnv = new StandardEnvironment();
+ springEnv.setActiveProfiles(springProfiles);
+ app.setEnvironment(springEnv);
+ }
+
+ app.run();
+
+ initialized = true;
+ Timer.stop("SPRINGBOOT_COLD_START");
+ }
+
+ private Class>[] getEmbeddedContainerClasses() {
+ Class>[] classes = new Class[2];
+ try {
+ // if HandlerAdapter is available we assume they are using WebFlux. Otherwise plain servlet.
+ this.getClass().getClassLoader().loadClass("org.springframework.web.reactive.HandlerAdapter");
+ log.debug("Found WebFlux HandlerAdapter on classpath, using reactive server factory");
+ classes[0] = ServerlessReactiveEmbeddedServerFactory.class;
+ } catch (ClassNotFoundException e) {
+ classes[0] = ServerlessServletEmbeddedServerFactory.class;
+ }
+
+ classes[1] = springBootInitializer;
+ return classes;
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/embedded/ServerlessReactiveEmbeddedServerFactory.java b/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/embedded/ServerlessReactiveEmbeddedServerFactory.java
new file mode 100644
index 000000000..94a9d2074
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/embedded/ServerlessReactiveEmbeddedServerFactory.java
@@ -0,0 +1,93 @@
+package com.amazonaws.serverless.proxy.spring.embedded;
+
+import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import org.springframework.boot.autoconfigure.AutoConfigureOrder;
+import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
+import org.springframework.boot.web.server.WebServer;
+import org.springframework.boot.web.server.WebServerException;
+import org.springframework.core.Ordered;
+import org.springframework.http.server.reactive.HttpHandler;
+import org.springframework.http.server.reactive.ServletHttpHandlerAdapter;
+
+import javax.servlet.*;
+import java.io.IOException;
+import java.util.Enumeration;
+
+@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
+public class ServerlessReactiveEmbeddedServerFactory extends AbstractReactiveWebServerFactory implements WebServer, Servlet {
+ private ServletHttpHandlerAdapter handler;
+ private ServletConfig config;
+ static final String SERVLET_NAME = "com.amazonaws.serverless.proxy.spring.embedded.ServerlessReactiveEmbeddedServerFactory";
+ static final String SERVLET_INFO = "ServerlessReactiveEmbeddedServerFactory";
+
+ @Override
+ @SuppressFBWarnings("MTIA_SUSPECT_SERVLET_INSTANCE_FIELD")
+ public WebServer getWebServer(HttpHandler httpHandler) {
+ handler = new ServletHttpHandlerAdapter(httpHandler);
+ return this;
+ }
+
+ @Override
+ public void start() throws WebServerException {
+ // register this object as the main handler servlet with a mapping of /
+ SpringBootLambdaContainerHandler
+ .getInstance()
+ .getServletContext()
+ .addServlet(SERVLET_NAME, this)
+ .addMapping("/");
+ handler.init(new ServletAdapterConfig());
+ }
+
+ @Override
+ public void stop() throws WebServerException {
+ // nothing to do here.
+ }
+
+ @Override
+ public void init(ServletConfig servletConfig) throws ServletException {
+ config = servletConfig;
+ }
+
+ @Override
+ public ServletConfig getServletConfig() {
+ return config;
+ }
+
+ @Override
+ public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
+ handler.service(servletRequest, servletResponse);
+ }
+
+ @Override
+ public String getServletInfo() {
+ return SERVLET_INFO;
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+
+ private static class ServletAdapterConfig implements ServletConfig {
+ @Override
+ public String getServletName() {
+ return SERVLET_NAME;
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ return SpringBootLambdaContainerHandler.getInstance().getServletContext();
+ }
+
+ @Override
+ public String getInitParameter(String s) {
+ return null;
+ }
+
+ @Override
+ public Enumeration getInitParameterNames() {
+ return null;
+ }
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/embedded/ServerlessServletEmbeddedServerFactory.java b/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/embedded/ServerlessServletEmbeddedServerFactory.java
new file mode 100644
index 000000000..b47b081c7
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/main/java/com/amazonaws/serverless/proxy/spring/embedded/ServerlessServletEmbeddedServerFactory.java
@@ -0,0 +1,55 @@
+package com.amazonaws.serverless.proxy.spring.embedded;
+
+import com.amazonaws.serverless.exceptions.ContainerInitializationException;
+import com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler;
+import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
+import org.springframework.boot.autoconfigure.AutoConfigureOrder;
+import org.springframework.boot.web.server.WebServer;
+import org.springframework.boot.web.server.WebServerException;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
+import org.springframework.core.Ordered;
+
+import javax.servlet.ServletException;
+
+@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
+public class ServerlessServletEmbeddedServerFactory implements ServletWebServerFactory, WebServer {
+ private ServletContextInitializer[] initializers;
+ private AwsLambdaServletContainerHandler handler;
+
+ public ServerlessServletEmbeddedServerFactory() {
+ super();
+ handler = SpringBootLambdaContainerHandler.getInstance();
+ }
+
+ @Override
+ public WebServer getWebServer(ServletContextInitializer... initializers) {
+ this.initializers = initializers;
+ for (ServletContextInitializer i : initializers) {
+ try {
+ if (handler.getServletContext() == null) {
+ throw new WebServerException("Attempting to initialize ServletEmbeddedWebServer without ServletContext in Handler", null);
+ }
+ i.onStartup(handler.getServletContext());
+ } catch (ServletException e) {
+ throw new WebServerException("Could not initialize Servlets", e);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public void start() throws WebServerException {
+
+ }
+
+ @Override
+ public void stop() throws WebServerException {
+
+ }
+
+ @Override
+ public int getPort() {
+ return 0;
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/ServletAppTest.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/ServletAppTest.java
new file mode 100644
index 000000000..b7353cd82
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/ServletAppTest.java
@@ -0,0 +1,24 @@
+package com.amazonaws.servlerss.proxy.spring;
+
+import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
+import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.servlerss.proxy.spring.servletapp.LambdaHandler;
+import com.amazonaws.servlerss.proxy.spring.servletapp.MessageController;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ServletAppTest {
+
+ LambdaHandler handler = new LambdaHandler();
+ MockLambdaContext lambdaContext = new MockLambdaContext();
+
+ @Test
+ public void helloRequest_respondsWithSingleMessage() {
+ AwsProxyRequest req = new AwsProxyRequestBuilder("/hello", "GET").build();
+ AwsProxyResponse resp = handler.handleRequest(req, lambdaContext);
+ assertEquals(MessageController.HELLO_MESSAGE, resp.getBody());
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/WebFluxAppTest.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/WebFluxAppTest.java
new file mode 100644
index 000000000..ffdb98e41
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/WebFluxAppTest.java
@@ -0,0 +1,32 @@
+package com.amazonaws.servlerss.proxy.spring;
+
+import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
+import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.servlerss.proxy.spring.webfluxapp.LambdaHandler;
+import com.amazonaws.servlerss.proxy.spring.webfluxapp.MessageController;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class WebFluxAppTest {
+
+ LambdaHandler handler = new LambdaHandler();
+ MockLambdaContext lambdaContext = new MockLambdaContext();
+
+ @Test
+ public void helloRequest_respondsWithSingleMessage() {
+ AwsProxyRequest req = new AwsProxyRequestBuilder("/single", "GET").build();
+ AwsProxyResponse resp = handler.handleRequest(req, lambdaContext);
+ assertEquals(MessageController.MESSAGE, resp.getBody());
+ }
+
+ @Test
+ public void helloDoubleRequest_respondsWithDoubleMessage() {
+ AwsProxyRequest req = new AwsProxyRequestBuilder("/double", "GET").build();
+ AwsProxyResponse resp = handler.handleRequest(req, lambdaContext);
+
+ assertEquals(MessageController.MESSAGE + MessageController.MESSAGE, resp.getBody());
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/LambdaHandler.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/LambdaHandler.java
new file mode 100644
index 000000000..c6b4e0b76
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/LambdaHandler.java
@@ -0,0 +1,25 @@
+package com.amazonaws.servlerss.proxy.spring.servletapp;
+
+import com.amazonaws.serverless.exceptions.ContainerInitializationException;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+
+public class LambdaHandler implements RequestHandler {
+ private static SpringBootLambdaContainerHandler handler;
+
+ static {
+ try {
+ handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(ServletApplication.class);
+ } catch (ContainerInitializationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) {
+ return handler.proxy(awsProxyRequest, context);
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/MessageController.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/MessageController.java
new file mode 100644
index 000000000..48731347b
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/MessageController.java
@@ -0,0 +1,15 @@
+package com.amazonaws.servlerss.proxy.spring.servletapp;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class MessageController {
+ public static final String HELLO_MESSAGE = "Hello";
+
+ @RequestMapping(path="/hello", method= RequestMethod.GET)
+ public String hello() {
+ return HELLO_MESSAGE;
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/ServletApplication.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/ServletApplication.java
new file mode 100644
index 000000000..c7050f1b3
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/servletapp/ServletApplication.java
@@ -0,0 +1,8 @@
+package com.amazonaws.servlerss.proxy.spring.servletapp;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class ServletApplication extends SpringBootServletInitializer {
+}
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/LambdaHandler.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/LambdaHandler.java
new file mode 100644
index 000000000..60dcbd4a3
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/LambdaHandler.java
@@ -0,0 +1,25 @@
+package com.amazonaws.servlerss.proxy.spring.webfluxapp;
+
+import com.amazonaws.serverless.exceptions.ContainerInitializationException;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+
+public class LambdaHandler implements RequestHandler {
+ private static SpringBootLambdaContainerHandler handler;
+
+ static {
+ try {
+ handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(WebFluxTestApplication.class);
+ } catch (ContainerInitializationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) {
+ return handler.proxy(awsProxyRequest, context);
+ }
+}
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/MessageController.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/MessageController.java
new file mode 100644
index 000000000..a507ff978
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/MessageController.java
@@ -0,0 +1,26 @@
+package com.amazonaws.servlerss.proxy.spring.webfluxapp;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Flux;
+
+@RestController
+public class MessageController {
+ public static final String MESSAGE = "Hello";
+
+ @RequestMapping(path="/single", method= RequestMethod.GET)
+ Flux singleMessage(){
+ return Flux.just(
+ MESSAGE
+ );
+ }
+
+ @RequestMapping(path="/double", method= RequestMethod.GET)
+ Flux doubleMessage(){
+ return Flux.just(
+ MESSAGE,
+ MESSAGE
+ );
+ }
+}
\ No newline at end of file
diff --git a/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/WebFluxTestApplication.java b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/WebFluxTestApplication.java
new file mode 100644
index 000000000..ec06ac4d8
--- /dev/null
+++ b/aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/servlerss/proxy/spring/webfluxapp/WebFluxTestApplication.java
@@ -0,0 +1,8 @@
+package com.amazonaws.servlerss.proxy.spring.webfluxapp;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.web.reactive.config.EnableWebFlux;
+
+@SpringBootApplication
+public class WebFluxTestApplication {
+}
diff --git a/pom.xml b/pom.xml
index 807aecd9b..00617337b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,7 @@
aws-serverless-spring-archetype
aws-serverless-springboot-archetype
aws-serverless-springboot2-archetype
+ aws-serverless-java-container-springboot2