[JAVA] I tried using the Server Push function of Servlet 4.0

** Servlet 4.0 ** supports HTTP / 2 and implements ** Server Push ** as the Servlet API. Sever Push is one of the features of HTTP / 2, which is the ability to proactively return a response from the server without waiting for a request from the client. Currently (May 20, 2017), the specifications are under development, but we will look at how to use them from the published contents.

Description

The Servlet 4.0 specification currently under development is published at JSR 369. One of the new features included in this JSR 369 is ** HTTP / 2 Server Push **.

Server Push

Up to HTTP / 1.1, it was usually a pair of requests / responses over a single TCP connection.

With HTTP / 2, it is now possible to proactively return multiple content responses from the server side without waiting for a request from a client on the same TCP connection.

This feature is called ** Server Push **.

Assumption: Operating environment

Use the beta version of Glass Fish 5 as the application server to run.

Implementation method

1. Create a project

Create a JavaEE project in Maven.

mvn archetype:generate \
  -DarchetypeGroupId=org.codehaus.mojo.archetypes \
  -DarchetypeArtifactId=webapp-javaee7 \
  -DarchetypeVersion=1.1 \
  -DinteractiveMode=false \
  -DgroupId=${GROUP_ID} \
  -DartifactId=${ARTIFACT_ID} \
  -Dversion=1.0.0-SNAPSHOT \
  -Dpackage=${GROUP_ID} \
  --batch-mode \
  --update-snapshots

--Set GROUP_ID and ARTIFACT_ID appropriately. --GROUP_ID: Equivalent to package name --ARTIFACT_ID: Equivalent to the project name

2. Edit pom.xml

2.1. Adding Servlet 4.0 dependencies

Edit the pom.xml included in the Java project you created. Add the following Servlet 4.0 API dependencies. Since Servlet 4.0 is integrated with Glass Fish 5, the scope is * provided *.

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.0-b05</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

2.2. Add build definition

Add a build definition. There are three additional viewpoints as follows. --Output file name --Compiler settings --WAR file settings

<build>
    <finalName>serverpush</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <compilerArguments>
                    <endorseddirs>${endorsed.dir}</endorseddirs>
                </compilerArguments>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <warSourceDirectory>src/main/webapp</warSourceDirectory>
                <packagingExcludes>
                    %regex[WEB-INF/lib/javax.servlet-api-.*.jar]
                </packagingExcludes>
                <webResources>
                    <resource>
                        <directory>src/main/resources</directory>
                    </resource>
                </webResources>
            </configuration>
        </plugin>
</build>
2.2.1. Output file name

By default, the context root is the WAR file name. It can be set on the server, but the output file name is fixed so that it is aligned as the default value.

2.2.2. Compiler settings

Set ** 1.8 ** to use the Java 8 API.

2.2.3. WAR file settings

This time, for the sake of simplicity, we will not use web.xml because we will define the Servlet in Annotation. Set failOnMissingWebXml so that there are no warnings.

3. Implementation of Server Push

There is only one point to use the Server Push API. It means getting a ** PushBuiler ** object. The Server Push function is implemented from PushBuilder.

Push Builder gets from HTTPServletRequest:

PushBuilder pushBuilder = request.newPushBuilder();

For this acquired PushBuilder object, set the placement path of the content you want to Server Push (send to the client side in advance). Here's how to set the path:

-** / Starting ** Path: Absolute path. / Specify the path including the context root below -** / Does not start ** Path: Specify a relative path from your own context

pushBuilder.path("bootstrap/css/bootstrap.min.css")

It is possible to additionally set the header information and query string, but by simply calling ** push () ** as it is, the content set by path () will be sent to the client side.

pushBuilder.push();

Push () clears the content path information. Once cleared, you can reuse the PushBuilder object and repeat ServerPush.

Server Push Implementation Status

HTTP/1.1 First, the HTML is acquired, and the content request is issued again for the content resource (CSS / JavaScript / image) to which the link is attached. You can also check the re-creation of the TCP connection.

HTTP / 2 Server Push None

HTTP / 2 is a protocol that allows multiple requests / responses to be made simultaneously within the same TCP connection. In fact, after getting the HTML for the first time, you can see that the request is issued at the same time for the content to which the link is attached.

HTTP / 2 Server Push implementation

You can see that the content using Server Push is being pushed asynchronously.

Summary

I find it convenient that the Server Push functionality will be provided in Servlet 4.0 in a standardized form. While it's convenient, it's not like you can push anything with Server, so I wanted to get a feel for what kind of screen and what content should be pushed in the future.

Recommended Posts

I tried using the Server Push function of Servlet 4.0
I tried using the cache function of Application Container Cloud Service
I tried using the profiler of IntelliJ IDEA
I tried using GoogleHttpClient of Java
I tried using the GitHub repository as a library server
[Swift] I tried to implement the function of the vending machine
I tried to build the environment of PlantUML Server with Docker
I tried to check the operation of gRPC server with grpcurl
[Rails] I will explain the implementation procedure of the follow function using form_with.
[API] I tried using the zip code search API
I tried to set tomcat to run the Servlet.
I tried to implement a server using Netty
I tried using Gson
I tried using TestNG
I tried using Galasa
I tried to summarize the state transition of docker
05. I tried to stub the source of Spring Boot
I tried to reduce the capacity of Spring Boot
I tried the new feature profiler of IntelliJ IDEA 2019.2.
I tried using the Migration Toolkit for Application Binaries
I tried using Log4j2 on a Java EE server
[WIP] I tried the configuration of Docker + Streama + NFS
I tried to investigate the mechanism of Emscripten by using it with the Sudoku solver
I tried using azure cloud-init
I tried the Docker tutorial!
I tried using Apache Wicket
I tried the VueJS tutorial!
I tried using Java REPL
I tried the FizzBuzz problem
I tried to implement the like function by asynchronous communication
I made the server side of an online card game ①
[Rails] I tried using the button_to method for the first time
I tried to summarize the basics of kotlin and java
I tried JAX-RS and made a note of the procedure
I tried to summarize the basic grammar of Ruby briefly
I tried to build the environment little by little using docker
I tried to build the environment of WSL2 + Docker + VSCode
[Rails] I tried to implement "Like function" using rails and js
I tried using the CameraX library with Android Java Fragment
I tried to touch the asset management application using the emulator of the distributed ledger Scalar DLT
I tried to develop the cache function of Application Container Cloud Service in the local environment
I tried using anakia + Jing now
I tried to solve the problem of "multi-stage selection" with Ruby
[Metal] I tried to figure out the flow until rendering using Metal
I tried to implement Ajax processing of like function in Rails
[Rails] Implementation of multi-layer category function using ancestry "I tried to make a window with Bootstrap 3"
I tried using Spring + Mybatis + DbUnit
User evaluation using the like function
I tried using JOOQ with Gradle
I read the source of ArrayList I read
I tried to implement the image preview function with Rails / jQuery
I tried the input / output type of Java Lambda ~ Map edition ~
I read the source of Integer
I tried to explain the method
Try using the two-point measurement function of Firebase Performance Monitoring. [Android]
I read the source of Long
I tried the Java framework "Quarkus"
[Rails] I tried deleting the application
I tried using Java8 Stream API
I tried using JWT in Java
I tried to summarize the methods of Java String and StringBuilder