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.

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

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.

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.

Referencias

Autor

Gerardo Arroyo Arce

Chief Technology Officer.

  • Ingeniero en Software. ITCR.
  • Master en Computación en Informática. UCR.
  • Oracle Certified Expert, JEE 6 Web Services Developer.
  • Oracle Certified Professional, Java SE 7 Programmer.
  • Oracle WebLogic Server 12c Certified Implementation Specialist.

Flecha Roja Technologies, 2017.