diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml
index a5693fcf8283..a324c46bcef8 100644
--- a/spring-boot-modules/pom.xml
+++ b/spring-boot-modules/pom.xml
@@ -126,6 +126,7 @@
spring-boot-openapi
spring-boot-brave
spring-boot-simple
+ spring-boot-http2
diff --git a/spring-boot-modules/spring-boot-http2/pom.xml b/spring-boot-modules/spring-boot-http2/pom.xml
new file mode 100644
index 000000000000..9aba813a9227
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/pom.xml
@@ -0,0 +1,53 @@
+
+ 4.0.0
+ spring-boot-http2
+ 0.0.1-SNAPSHOT
+ spring-boot-http2
+ Demo project for Spring Boot
+
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+ ch.qos.logback
+ logback-core
+ ${logback.version}
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 11
+ 11
+
+ -parameters
+
+
+
+
+
+
+ 3.4.3
+ 1.5.17
+
+
diff --git a/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/Http2Application.java b/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/Http2Application.java
new file mode 100644
index 000000000000..a79505fe0c0e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/Http2Application.java
@@ -0,0 +1,13 @@
+package com.baeldung.http2;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Http2Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Http2Application.class, args);
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/config/Http2Config.java b/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/config/Http2Config.java
new file mode 100644
index 000000000000..bacf007f7ac1
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/config/Http2Config.java
@@ -0,0 +1,25 @@
+package com.baeldung.http2.config;
+
+import org.apache.catalina.connector.Connector;
+import org.apache.coyote.http2.Http2Protocol;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+@Configuration
+@Profile("config-class")
+public class Http2Config {
+
+ @Bean
+ public WebServerFactoryCustomizer getWebServerFactoryCustomizer() {
+ return factory -> {
+ Connector httpConnector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
+ httpConnector.setPort(8080);
+ factory.addConnectorCustomizers(connector -> connector.addUpgradeProtocol(new Http2Protocol()));
+ factory.addAdditionalTomcatConnectors(httpConnector);
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/controller/Http2Controller.java b/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/controller/Http2Controller.java
new file mode 100644
index 000000000000..23af24d3b27e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/main/java/com/baeldung/http2/controller/Http2Controller.java
@@ -0,0 +1,15 @@
+package com.baeldung.http2.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class Http2Controller {
+
+ @GetMapping("/http2/echo")
+ public String getEcho(@RequestParam String message) {
+ return message;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-http2/src/main/resources/application-config-class.yml b/spring-boot-modules/spring-boot-http2/src/main/resources/application-config-class.yml
new file mode 100644
index 000000000000..fdcfe1c15f8e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/main/resources/application-config-class.yml
@@ -0,0 +1,12 @@
+server:
+ http2:
+ enabled: false
+
+ port: 8443
+
+ ssl:
+ enabled: true
+ key-store: classpath:keystore.p12
+ key-store-password: abcd1234
+ key-store-type: PKCS12
+ key-alias: http2-alias
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-http2/src/main/resources/application.yml b/spring-boot-modules/spring-boot-http2/src/main/resources/application.yml
new file mode 100644
index 000000000000..e3e6b4a85836
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/main/resources/application.yml
@@ -0,0 +1,12 @@
+server:
+ http2:
+ enabled: true
+
+ port: 8443
+
+ ssl:
+ enabled: true
+ key-store: classpath:keystore.p12
+ key-store-password: abcd1234
+ key-store-type: PKCS12
+ key-alias: http2-alias
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-http2/src/main/resources/keystore.p12 b/spring-boot-modules/spring-boot-http2/src/main/resources/keystore.p12
new file mode 100644
index 000000000000..1cf25c4fa9d6
Binary files /dev/null and b/spring-boot-modules/spring-boot-http2/src/main/resources/keystore.p12 differ
diff --git a/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/AllCertsTrustManager.java b/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/AllCertsTrustManager.java
new file mode 100644
index 000000000000..586810942fc6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/AllCertsTrustManager.java
@@ -0,0 +1,18 @@
+package com.baeldung.http2;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.X509Certificate;
+
+public class AllCertsTrustManager implements X509TrustManager {
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs, String authType) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs, String authType) {
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/Http2ApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/Http2ApplicationIntegrationTest.java
new file mode 100644
index 000000000000..d1e4cc7c27cd
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/Http2ApplicationIntegrationTest.java
@@ -0,0 +1,65 @@
+package com.baeldung.http2;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.server.LocalServerPort;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+// Integration test based on enabling HTTP/2 using the configuration in application.yml
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class Http2ApplicationIntegrationTest {
+
+ private static SSLContext sslContext;
+
+ @LocalServerPort
+ private int port;
+
+ private HttpClient httpClient;
+
+ @BeforeAll
+ static void setupOnce() throws NoSuchAlgorithmException, KeyManagementException {
+ // Get rid of cert validation due to the self-signed certificate
+ sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null,
+ new TrustManager[] { new AllCertsTrustManager() },
+ new java.security.SecureRandom());
+ }
+
+ @BeforeEach
+ void setup() {
+ httpClient = HttpClient.newBuilder()
+ .sslContext(sslContext)
+ .version(HttpClient.Version.HTTP_2)
+ .build();
+ }
+
+ @Test
+ void whenSendHttp2Request_thenReturnHttp2Response() throws Exception {
+ // when
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(new URI(String.format("https://localhost:%s/http2/echo?message=test", port)))
+ .GET()
+ .build();
+ HttpResponse> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+ // then
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("test");
+ assertThat(response.version()).isEqualTo(HttpClient.Version.HTTP_2);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/Http2ConfigClassApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/Http2ConfigClassApplicationIntegrationTest.java
new file mode 100644
index 000000000000..a475c1e589e0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-http2/src/test/java/com/baeldung/http2/Http2ConfigClassApplicationIntegrationTest.java
@@ -0,0 +1,8 @@
+package com.baeldung.http2;
+
+import org.springframework.test.context.ActiveProfiles;
+
+// Integration test based on enabling HTTP/2 using the configuration class Http2Config
+@ActiveProfiles("config-class")
+class Http2ConfigClassApplicationIntegrationTest extends Http2ApplicationIntegrationTest {
+}
\ No newline at end of file