¿Ya sabes cómo escribir aplicaciones en Java que muestran texto en la consola, pero aún no tienes claro cómo crear tu primera aplicación web? Excelente, este es el lugar indicado.
En este Java Servlet tutorial, te guiaré para que te familiarices con los servlets y escribas una aplicación que podrás mostrar a tus amigos sin necesidad de enviarles un archivo JAR ni obligarlos a instalar Java.
¿Qué es un Servlet?
Un servlet es una tecnología del lenguaje de programación Java que permite crear aplicaciones web dinámicas. Funciona como un intermediario en el servidor, recibiendo peticiones de los clientes (navegadores) y generando respuestas personalizadas, como páginas HTML. En esencia, es el componente clave que gestiona la comunicación en una arquitectura cliente-servidor en Java.
Para aclarar a fondo qué es un servlet y por qué se menciona con tanta frecuencia, piensa en él como una interfaz especial en el lenguaje de programación Java, necesaria para el intercambio de información entre la parte del servidor y la parte del cliente de un programa.
El Java Servlet se aloja en el servidor, recibe peticiones del cliente y envía respuestas a estas. Gestiona la comunicación entre las distintas partes de la aplicación.
En efecto, los servlets en Java son los elementos con los que se construye la arquitectura cliente-servidor.
El procesamiento de solicitudes es la base del desarrollo de aplicaciones web en Java. Para responder a las solicitudes de la red, una aplicación web Java primero debe determinar qué código responderá a la URL de la solicitud y luego enrutar la respuesta. Cada stack tecnológico tiene una forma de realizar el procesamiento de solicitud-respuesta. En Java, los servlets se utilizan para este propósito.
Para entenderlo mejor, se puede imaginar un servlet como un especialista que realiza una tarea específica, y el contenedor como el gestor que organiza su trabajo.
¿Para Qué Sirve un Servlet Exactamente?
Es posible escribir programas simples que muestran información en la consola y no interactúan con la web sin necesidad de servlets. Sin embargo, para aplicaciones con una arquitectura cliente-servidor, son indispensables: constituyen el mecanismo principal mediante el cual el cliente y el servidor se comunican en Java.
Un servlet te permite:
- Crear páginas dinámicas, es decir, aquellas cuyo contenido se carga sobre la marcha.
- Solicitar información a una base de datos y recibir una respuesta.
- Recopilar información de los usuarios a través de formularios de registro.
- Mostrar mensajes en respuesta a una petición y realizar muchas otras tareas.
El Funcionamiento Interno: Arquitectura y Ciclo de Vida
El software como capas
Cada nivel en un sistema de software contiene capacidades específicas que son requeridas por las capas superiores.
Como ejemplo, el nivel de hardware se encuentra por debajo del nivel de firmware, soportando su funcionalidad. Análogamente, para iniciar el sistema operativo, es necesario el nivel de firmware (BIOS en PC o EFI en Mac).
También puedes ver un sistema de software como una serie de contenedores, donde las capas inferiores actúan como contenedores para las superiores.
Cada nivel actúa como un contexto para la ejecución del siguiente nivel de funcionalidad: el hardware contiene el firmware, y el firmware contiene el sistema operativo.
Java en el Servidor y el Servlet Container
Una aplicación Java de servidor pertenece a una amplia clase de aplicaciones que actúan como endpoints de red, recibiendo solicitudes HTTP desde una URL específica y devolviendo datos en un formato de intercambio, como HTML o JSON.
Un servlet es simplemente código que describe cómo responderá el servidor a las peticiones. Para que funcione, se requiere un software especial denominado Servlet Container. Este se encarga de la creación y eliminación de las instancias.
El contenedor de servlets se instala en el servidor. Su tarea principal es dar soporte a la operación de los servlets: recibirlos, ejecutarlos, supervisar su ejecución y, si es necesario, destruirlos.
En los sistemas Java, el sistema operativo (SO) contiene la JVM, que proporciona un entorno consistente para la ejecución de aplicaciones Java. El servidor Java se encuentra sobre la JVM.
De la misma manera que la JVM es un intermediario entre el SO y tu aplicación Java, el servidor Java proporciona un acceso consistente y simplificado a las capacidades de red y procesamiento del sistema operativo. La aplicación Java se ejecuta dentro del servidor, utilizando una API para acceder a las capacidades del servidor.
La especificación: De Java Servlet a Jakarta Servlet
La especificación de Jakarta Servlet proporciona la definición base para un servidor Java y sus componentes asociados. Define cómo un servidor enviará solicitudes y respuestas durante las interacciones de red a través de HTTP.
Los servidores Java modernos implementan la especificación de Jakarta Servlet para garantizar un comportamiento consistente en el manejo de solicitudes HTTP. Los servidores Java modernos ofrecen compatibilidad con Jakarta Servlet 6.1 (estable desde 2024 y parte de Jakarta EE 11), especialmente en sus versiones más recientes.
Nota: Servlet 4.0 (de ~2017–2018) ya es muy antiguo; desde 2019–2020 la tecnología migró de “Java Servlet” (javax.servlet) a “Jakarta Servlet” (jakarta.servlet) tras la transferencia de Oracle a Eclipse Foundation. Para proyectos antiguos, puede ser útil la herramienta de migración de Tomcat.
El Ciclo de Vida de un Servlet
El contenedor recibe y carga el servlet. Un servlet se presenta como una clase. El contenedor, después de cargar el servlet, crea una instancia funcional de este.
- Inicialización: Para la configuración preliminar, o inicialización, de la instancia, el contenedor invoca un método especial,
init(). Este es un método estándar responsable de poner el servlet en estado operativo. - Manejo de Peticiones: Tras la ejecución del método
init(), el servlet está listo para operar. Cuando llega una nueva petición, el contenedor invoca para él el métodoservice(). Dentro de este método, se determina el tipo de la petición y se redirige al método correspondiente (doGet,doPost, etc.).Los servlets operan de manera multifilial (multithreaded). El contenedor utiliza un pool de hilos para procesar las peticiones, lo que permite que el servidor atienda múltiples solicitudes simultáneamente de forma eficiente. - Destrucción: Si el servlet ya no es necesario, el contenedor destruye la instancia en ejecución. Para ello, invoca el método especial
destroy().
Manos a la Obra: Creando tu Primera Aplicación Web
Ahora que tienes una visión conceptual, empecemos a escribir un servlet de Java.
Requisitos
Para trabajar cómodamente, necesitarás un IDE como IntelliJ IDEA (la versión Community Edition gratis es más que suficiente para servlets puros y una configuración Java Servlet Tomcat – ¡no necesitas pagar nada al inicio!). Si te interesa, he escrito sobre los mejores IDE para Java en otro artículo.
Si más adelante quieres meterte con Spring Boot o frameworks más avanzados, ahí sí considera el Ultimate (con trial gratis de 30 días). Tomcat es un contenedor de servlets (y servidor web Java); es el componente que procesa las solicitudes HTTP entrantes y las transfiere a nuestra aplicación.
Lo primero que necesitarás es un contenedor de servlets. Utilizaremos Tomcat porque es uno de los contenedores de servlets más antiguos y utilizados en el ecosistema Java.
Paso 1: Descarga e instala Tomcat
Si aún no tienes Tomcat, empieza por abrir la página de descargas de Tomcat. Recomiendo la versión 11.0.x, que implementa Jakarta Servlet 6.1. Allí puedes seleccionar el instalador de Windows o la versión ZIP más adecuada para tu sistema. Recuerda que Tomcat 11 requiere JDK 17 o superior.
Antes de continuar, asegúrate de que puedes iniciar Tomcat. Cuando abras un navegador web y navegues a localhost:8080, deberías ver la página de bienvenida de Tomcat 11 (con el logo y estilo moderno actual.)
Paso 2: Escribir el Código del Servlet “Hola Mundo”
Para crear un servlet, implementas la interfaz Servlet (normalmente extendiendo HttpServlet) y lo despliegas dentro de un contenedor de servlets. Este es un clásico Servlet Java ejemplo.
Listado 1. Código fuente del ejemplo Hello World actualizado (Jakarta Servlet 6.1)
import java.io.*;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.WebServlet;
@WebServlet("/hello")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
}
}Analicemos este código. Las primeras líneas realizan las importaciones (ahora con paquete jakarta.servlet.*). Después, la clase MainServlet extiende la clase HttpServlet.
A continuación, la clase define un método llamado doGet(). Este le indica al servidor que dirija las solicitudes HTTP GET a este método. doGet() tiene dos parámetros: HttpServletRequest request y HttpServletResponse response. Estos dos objetos representan la solicitud y la respuesta. En el método, el objeto de respuesta se utiliza para informar al servidor qué tipo de contenido debe emitir.
Finalmente, el programa obtiene un objeto PrintWriter de Java a partir de la respuesta con response.getWriter() y se utiliza para construir una respuesta HTML.
Paso 3: El Mapeo de la URL
¿Cómo sabe el servidor que debe asociar una URL con el método MainServlet.doGet()? En este ejemplo moderno, usamos la anotación @WebServlet("/hello") (disponible desde Servlet 3.0 y estándar recomendado hoy). Esto vincula (mapea) el servlet a una ruta específica.
En aplicaciones legacy aún se puede usar web.xml, pero en 2026 es opcional.
Llevando tu Servlet al Siguiente Nivel
Mejoremos nuestro servlet para que pueda procesar parámetros de solicitud y trabajar con la sesión.
Trabajando con Parámetros y Java Servlet Session
import java.io.*;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.WebServlet;
@WebServlet("/hello")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
Integer visitCounter = (Integer) session.getAttribute("visitCounter");
if (visitCounter == null) {
visitCounter = 1;
} else {
visitCounter++;
}
session.setAttribute("visitCounter", visitCounter);
String username = req.getParameter("username");
resp.setContentType("text/html;charset=UTF-8");
try (PrintWriter printWriter = resp.getWriter()) {
if (username == null) {
printWriter.write("Hello, Anonymous" + "<br>");
} else {
printWriter.write("Hello, " + username + "<br>");
}
printWriter.write("Page was visited " + visitCounter + " times.");
}
}
}Ahora el servlet trabaja con la sesión, incrementando el contador visitCounter en cada visita. Del objeto HttpServletRequest podemos obtener toda la información necesaria sobre la solicitud. Si el atributo visitCounter aún no ha sido creado, el método getAttribute() devolverá null, por lo que es necesario realizar una comprobación de nulos. Lo mismo aplica para los parámetros de la solicitud con req.getParameter("username").
Para pasar un parámetro en una solicitud GET, se utilizan parámetros de consulta (query parameters), es decir, es necesario acceder al enlace http://localhost:8080/hello?username=Leo.
Redirección vs. Reenvío: ¿Forward o Redirect?
Si creamos un servlet en la ruta raíz @WebServlet(“/”), su tarea puede ser redirigir las solicitudes a la ruta /hello. En proyectos reales, esta ruta suele gestionarse con cuidado para evitar conflictos con el servlet por defecto del contenedor. Esto se puede hacer de dos maneras:
- forward: delega el procesamiento de la solicitud a otro servlet en el servidor, sin involucrar al cliente. El cliente no ve el cambio de URL.
getServletContext().getRequestDispatcher("/hello").forward(req, resp); - redirect: devuelve al cliente la dirección a la que debe dirigirse. El navegador del cliente realiza una nueva solicitud a la nueva URL.
resp.sendRedirect(req.getContextPath() + "/hello");
El código del nuevo servlet sería:
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Elige una de las dos opciones
// Opción 1: Forward
// getServletContext().getRequestDispatcher("/hello").forward(req, resp);
// Opción 2: Redirect
resp.sendRedirect(req.getContextPath() + "/hello");
}
}¿Cuál es la Diferencia entre un Servlet y un JSP?
Una pregunta muy común al empezar es cómo se relaciona un Servlet con las JSP (JavaServer Pages). La diferencia es fundamental y clave para entender la arquitectura web en Java:
- Servlet: Se encarga de la lógica de negocio. Es puro código Java diseñado para procesar datos, interactuar con bases de datos y tomar decisiones. Es el “cerebro” de la operación.
- JSP: Se encarga de la presentación. Es un archivo similar al HTML que se utiliza para mostrar la información al usuario. Es la “vista” o la interfaz.
En una aplicación bien diseñada, un Servlet nunca genera HTML directamente. En su lugar, procesa la petición, prepara los datos y luego los “envía” a una página JSP para que esta los muestre de forma ordenada.
Para entender a fondo cómo se complementan y por qué esta separación es tan importante, te recomiendo leer nuestra guía detallada sobre la diferencia entre Servlet y JSP.
Tu Viaje con Java Servlets Apenas Comienza
¡Tu primera aplicación web está lista!
Este artículo ha sido una revisión conceptual y práctica de los servlets de Java, incluyendo el manejo de URLs y el procesamiento de respuestas dentro de un servidor Java. Comprender estos elementos fundamentales de la tecnología Java del lado del servidor te ayudará a integrar conceptos más avanzados.
Utilizando servlets tan simples, es posible construir aplicaciones web complejas y multifuncionales. Por supuesto, usando grandes frameworks como Spring, esto es mucho más sencillo. ¡Ahora estás listo para desarrollar con la versión actual!
Si quieres seguir profundizando, te recomiendo explorar la documentación oficial de Tomcat 11.