En este artículo daremos un ejemplo de Server Push, una de las nuevas características de Servlet 4.0 JSR 369 que fue liberado oficialmente en setiembre de 2017.

Esta característica de HTTP/2 brinda un mecanismo para hacer ‘push’ de recursos desde el servidor hacia el cliente. De esta manera, aplicaciones del lado del servidor son capaces de enviar contenido al cliente al inicio de la primera petición, en lugar de esperar a peticiones del cliente. Su objetivo principal es mejorar el rendimiento en la navegación de los usuarios.

Es importante aclarar que Server Push no es un reemplazo de WebSockets.

Dependencias


Para este caso, nuestro POM es muy sencillo. Solamente debemos indicar que el javaee-web-api es la versión 8.0.

No olviden usar un servidor de aplicaciones que cumpla con la especificación de JEE 8. Para este ejemplo usaremos la implementación de refencia, que es GlassFish 5.

<dependencies>
      <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-web-api</artifactId>
          <version>8.0</version>
          <scope>provided</scope>
      </dependency>
  </dependencies>

HTML


Nuestro página de pruebas es bastante básica. Utiliza bootstrap, hace referencia a una imagen y tres javascripts.

<!DOCTYPE html>
<html>
    <head>
        <title>Ejemplo de Servlet Push</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="css/bootstrap.css" />

    </head>
    <body>
        <img src="images/logo.svg" alt="Logo de Flecha Roja" />
        <h1>Servlet Push con JEE 8</h1>


        <script src="js/jquery-3.2.1.slim.min.js"></script>
        <script src="js/popper.min.js"></script>
        <script src="js/bootstrap.js" ></script>
    </body>
</html>

Comportamiento Normal


Si ejecutamos este aplicación tal cual (que por cierto usa solo html), veremos como el iniciador de las peticiones es el parser, el cual parsea el HTML y carga la imagen, el css y los javascripts.

Servlet


El servlet que creamos, va a responder al URL /push. Observen como se emplea la nueva clase PushBuilder.

@WebServlet(name = "Push", urlPatterns = {"/push"})
public class PushServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //Retorna una instancia de PushBuilder si HTTP/2 esta habilitado o null en caso contrario
        PushBuilder pushBuilder = request.newPushBuilder();

        if (pushBuilder != null) {
            // Hacemos un push del logo
            pushBuilder
                    .path("images/logo.svg")
                    .addHeader("content-type", "image/svg")
                    .push();

            pushBuilder
                    .path("css/bootstrap.css")
                    .push();

            pushBuilder
                    .path("js/jquery-3.2.1.slim.min.js")
                    .push();
            pushBuilder
                    .path("js/popper.min.js")
                    .push();
            pushBuilder
                    .path("js/bootstrap.js")
                    .push();

            request.getRequestDispatcher("index.html").forward(request, response);
        } else {
            super.doGet(request, response);
        }
    }

Por tanto, cuando se hace una petición GET al Servlet, la imagen, css y javascripts a la cual se le hace ‘push’ es accesible para el browser casi al mismo tiempo. Por lo consiguiente, esos recursos no van a iniciar nuevas peticiones hacia el servidor, pues ya ha sido enviado de manera proactiva al cliente.

Observamos que -a diferencia del primer caso- el iniciador del request sobre los recursos es el servlet que acabamos de programar. Algo importante, cuando realicen la prueba deben recordar que HTTP2 solo funciona sobre HTTPS.

Propiedades

Conclusión


La nueva especificación de Servlet 4 incluye varios elementos que debemos considerar durante el desarrollo de nuevos sistemas; en particular el server push puede ayudar a mejorar el rendimiento al poder enviar recursos proactivamente al cliente.

El código fuente de este artículo esta disponible en https://github.com/FlechaRoja/ServletPush

Referencias