Using HTTP/2 in your Spring Boot application

Published on - Updated on

Prerequisites

For this tutorial I’m assuming that you have a Unix-based environment on which you are able to run both the openssl and curl commands.

Generating a test project

Using https://start.spring.io, generate a simple Spring Boot application according to the specifications shown below.

Once generated, open this project in your favorite IDE, so we can start adding HTTP/2.

Creating an endpoint for testing

In your main application package create a simple TestController class, that we can use to verify our Spring Boot application is running HTTP/2.

@RestController
public class TestController {
    @GetMapping
    public String test() {
        return "successful";
    }
}

Let’s start up our application and have a look.

curl http://127.0.0.1:8080

This should return the string successful.

Enabling HTTP/2 at the Spring Boot level

In the application.properties file, enable HTTP/2 and restart the application.

server.http2.enabled=true

Now, let’s use curl to validate the HTTP version in use.

curl -sI http://127.0.0.1:8080

This provides us with a response, like the one shown below.

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 10
Date: Sat, 01 Feb 2020 09:45:54 GMT

Based on the first line of the response: HTTP/1.1 200, we can easily spot the fact that HTTP/1.1 is still being used. The reason for this is that HTTP/2 only works over HTTPS. Let’s enable HTTPS on our application and verify that this is indeed the missing component.

Setting up HTTPS

In order to be able to set up HTTPS in our local environment, we need to have an SSL certificate. Let’s generate a self-signed certificate that we can use for testing purposes. Use the command below to generate this certificate. (Source: Let’s Encrypt)

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

This generates two files localhost.crt, the public key, and localhost.key, the private key.

We can now use openssl to generate a PKCS truststore file that contains both our certificate and key.

openssl pkcs12 -export -in localhost.crt -inkey localhost.key -name localhost -out localhost.p12

The result of this command is a localhost.p12 file that we can use in our application. Copy this keystore file to your src/main/resources directory of your project and add the below configuration to your application.properties file in order to configure HTTPS. (make sure to replace <password> with the password you entered when generating the PKCS file)

# Changes the server port used by Spring Boot to the default one used for HTTPS on Tomcat
server.port=8443
# The format used for the keystore. It could be set to JKS in case it is a JKS file
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:localhost.p12
# The password used to generate the certificate
server.ssl.key-store-password=<password>
# The alias mapped to the certificate
server.ssl.key-alias=localhost

This should be everything to enable HTTPS for the application.

Putting our configuration to the test

Finally, start the application and use the curl command to connect to our test endpoint. (I’m using the -k option, as curl does not by default trust self-signed certificates)

curl -k -sI https://127.0.0.1:8443

The output of this should show that HTTP/2 is now successfully enabled.

HTTP/2 200
content-type: text/plain;charset=UTF-8
content-length: 10
date: Sat, 01 Feb 2020 10:15:09 GMT

Congratulations, you’ve successfully upgraded your application to use HTTP/2. There are still a couple of other things you could configure, such as a redirect from HTTP to HTTPS at the Tomcat level and setting up Spring Security to force SSL on all connections. Below in the references you can find a tutorial explaining this in more detail.

References