Friday, 5 April 2024

Enable HTTP/2 in spring boot 3 application

 

HTTP/2, commonly pronounced as "http two," marks a notable advancement in the Hypertext Transfer Protocol (HTTP), the backbone of communication between web servers and browsers. Unveiled in 2015, its primary objective is to elevate website performance and enrich user experience.

 

Let's delve into the pivotal features and advantages of HTTP/2:

 

Key Enhancements:

Multiplexing: This feature is revolutionary. Unlike its predecessor, HTTP/1.1, which constrained connections to handling one request at a time, HTTP/2 enables concurrent requests and responses via a single TCP connection. This eradicates the delay induced by sequential processing in HTTP/1.1, particularly beneficial for websites inundated with numerous resources like images, scripts, and stylesheets.

 

Binary Protocol: HTTP/2 deploys a binary format instead of HTTP/1.1's human-readable text format. This refinement streamlines data transmission, rendering it more compact and efficient.

 

Header Compression: HTTP/1.1 headers are often verbose and redundant, consuming unnecessary bandwidth and increasing latency. HTTP/2 utilizes header compression techniques such as Huffman encoding and HPACK to reduce the overhead of transmitting headers, resulting in more efficient use of network resources.

 

Stream Prioritization: HTTP/2 allows clients to assign priority to different streams, enabling more efficient resource allocation and better handling of critical resources. This ensures that important resources, such as CSS files or images, are prioritized for faster delivery.

 

Overall Advantages:

Accelerated Page Loading: By mitigating HTTP/1.1's constraints, HTTP/2 substantially accelerates website loading times, particularly evident on pages abundant with resources.

 

Enhanced User Experience: Quicker loading makes browsing easier and websites feel more responsive for people.

 

Optimized Efficiency: The reduction in data transmission overhead attributed to multiplexing, binary format adoption, and header compression translates into diminished bandwidth consumption for both servers and clients.

 

Adoption and Security:

 

Presently, HTTP/2 enjoys widespread support across modern browsers and web servers. It's noteworthy that HTTP/2 predominantly operates over HTTPS connections, which furnish encryption for secure communication. This is owing to HTTP/2's integration of TLS/SSL features within HTTPS, fortifying data security.

 

How to enable http2 in spring boot application?

We can enable http2 support in spring boot by adding below application property.

server:
  http2:
    enabled: true

 

When set to true, it indicates that the server should support the HTTP/2 protocol, allowing clients to communicate with the server using HTTP/2. This enables features like multiplexing, header compression, and server push, which can enhance the performance and efficiency of web applications, especially for modern browsers that support HTTP/2.

 

However, it's important to note that HTTP/2 requires HTTPS to be fully utilized in most modern browsers. If your application is running on HTTPS (which is highly recommended for security reasons), enabling HTTP/2 can further improve the performance of your web application.

 

Is HTTP/2 requires https?

Yes, HTTP/2 is essentially only enabled on HTTPS connections. Enabling HTTP/2 on your server typically requires an SSL/TLS certificate to establish the secure connection with HTTPS.

 

Follow below step by step procedure to build a spring boot application with HTTP/2 support.

 

Setting up HTTPS

To set up HTTPS on our local computer, we need an SSL certificate. Let's make a self-signed certificate for testing. Use this command to create it.

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 creates two files: localhost.crt, which is the public key, and localhost.key, which is the private key.

$ ls
localhost.crt	localhost.key

Now, we can utilize openssl to create a PKCS truststore file that includes both our certificate and key.

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

 

Above command need a paasword to generate truststore file. I set password as password123.

 

The outcome of this command is a localhost.p12 file, which we can integrate into our application. Transfer this keystore file to the src/main/resources directory of your project, and incorporate the following configuration into your application.yml file to set up HTTPS.

 

server:
  http2:
    enabled: true
  port: 8443
  ssl:
    key-store-type: PKCS12
    key-store: classpath:localhost.p12
    key-store-password: password123
    key-alias: localhost

Follow step-by-step procedure to build the working application.

 

Step 1: Create new maven project ‘springboot3-http2’.

 

Step 2: Update pom.xml with maven dependencies.

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.sample.app</groupId>
	<artifactId>springboot3-http2</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<maven.compiler.source>17</maven.compiler.source>
		<maven.compiler.target>17</maven.compiler.target>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.2.2</version>
	</parent>

	<dependencies>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
			<version>2.0.4</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Step 3: Create application.yml file under src/main/resources folder.

 

application.yml

server:
  http2:
    enabled: true
  port: 8443
  ssl:
    key-store-type: PKCS12
    key-store: classpath:localhost.p12
    key-store-password: password123
    key-alias: localhost

Step 4: Copy ‘localhost.p12’ file to src/main/resources folder.

 

Step 5: Define SwaggerConfig file.

 

SwaggerConfig.java

package com.sample.app.config;

import org.springframework.context.annotation.Configuration;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;

@Configuration
@OpenAPIDefinition(info = @Info(title = "Hello service Application", version = "v1"))
public class SwaggerConfig {

}

Step 6: Define HelloController class.

 

HelloController.java

package com.sample.app.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin("*")
@RequestMapping(value = "/apis/v1")
public class HelloController {
	
	@GetMapping("/hello")
	public ResponseEntity<String> sayHello(){
		return ResponseEntity.ok("Hello World");
	}

}

Step 7: Define main application class.

 

App.java

package com.sample.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

Total project structure looks like below.




Build the project

Go to the folder where pom.xml is located and execute below command.

mvn package

It generate ‘springboot3-http2-0.0.1-SNAPSHOT.jar’ file in target folder.

Execute below command to run the application.

java -jar ./target/springboot3-http2-0.0.1-SNAPSHOT.jar

Execute below command to confirm whether the application is accepting HTTP/2 or not.

curl -k -sI https://localhost:8443/apis/v1/hello

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

$ curl -k -sI https://localhost:8443/apis/v1/hello
HTTP/2 200 
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
content-type: text/plain;charset=UTF-8
content-length: 11
date: Fri, 05 Apr 2024 11:23:05 GMT

Congratulations, you’ve successfully upgraded your application to use HTTP/2.

 

is enabling HTTP/2 in spring boot app has any backward compatibility issues with http1 clients?

Enabling HTTP/2 in a Spring Boot app usually doesn't cause problems for HTTP/1.1 clients. Here's why:

 

1.   HTTP/2 is Designed for Compatibility: HTTP/2 is made to work with HTTP/1.1 clients. Even if a client only knows HTTP/1.1, it can still talk to an HTTP/2 server.

2.   How the Server Behaves: When a client connects, the server checks what version of HTTP it understands. If it's HTTP/1.1, the server talks to it in HTTP/1.1 for that connection. It's like a server speaking both languages fluently.

3.   Spring Boot Settings: Spring Boot doesn't force HTTP/2. If you turn it on, you usually just configure your server (like Tomcat) to say it can speak HTTP/2 during the connection setup.

4.   Keep in Mind: While most clients work fine, some very old or unusual HTTP/1.1 clients might have trouble. But these are rare these days.

 

Overall, turning on HTTP/2 in your Spring Boot app is usually safe and smart for modern web apps. It gives a speed boost to clients that can use it while still playing nice with older clients.


You can download this application from this link.


Previous                                                 Next                                                 Home

No comments:

Post a Comment