La funcionalidad de inicio de sesión es una característica omnipresente en la mayoría de las aplicaciones web modernas. Una vez que un usuario se autentica correctamente, el sistema lo dirige a una página de destino, como un panel de usuario o una página de confirmación. Este artículo explora cómo construir un sistema básico de autenticación y redirección utilizando Servlets de Java, demostrando la captura de datos del formulario y el reenvío a una vista de éxito.
Diseño del Servlet de Procesamiento de Autenticación
El servlet será el componente central encargado de recibir y procesar la información enviada desde el formulario de inicio de sesión, como las credenciales del usuario y cualquier otro dato adicional, para luego gestionar la navegación del usuario hacia la vista apropiada.
package com.example.webapp;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet; // Anotación para mapear el servlet sin web.xml
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays; // Utilidad para imprimir arrays
@WebServlet("/autenticar") // Mapea este servlet a la URL /autenticar
public class GestorAutenticacionServlet extends HttpServlet {
private static final long serialVersionUID = 1L; // ID de serialización
@Override
protected void doPost(HttpServletRequest solicitud, HttpServletResponse respuesta)
throws ServletException, IOException {
// Establecer la codificación de caracteres para evitar problemas con UTF-8
solicitud.setCharacterEncoding("UTF-8");
respuesta.setCharacterEncoding("UTF-8");
// Extraer los parámetros del formulario HTML
String nombreDeUsuario = solicitud.getParameter("nombreDeUsuario");
String claveDeAcceso = solicitud.getParameter("claveDeAcceso");
String[] preferenciasUsuario = solicitud.getParameterValues("preferencias");
// Simulación de validación de credenciales (en un escenario real, se interactuaría con una capa de servicio/DAO)
System.out.println("Solicitud de acceso - Usuario: " + nombreDeUsuario + ", Contraseña: " + claveDeAcceso);
if (preferenciasUsuario != null && preferenciasUsuario.length > 0) {
System.out.println("Preferencias seleccionadas: " + Arrays.toString(preferenciasUsuario));
} else {
System.out.println("El usuario no seleccionó preferencias.");
}
// Después de procesar, redirigir internamente a la página de éxito.
// Utilizar RequestDispatcher.forward() mantiene los objetos de solicitud y respuesta.
solicitud.getRequestDispatcher("/confirmacion-acceso.jsp").forward(solicitud, respuesta);
}
// El método doGet no está implementado para este ejemplo, ya que el formulario usa POST.
// Si se intentara acceder vía GET, se invocaría el método de la superclase (HttpServlet),
// que por defecto genera un error 405 (Method Not Allowed).
}
Formulario de Acceso de Usuario (index.jsp)
La siguiente página JSP proporciona la interfaz de usuario para que los usuarios ingresen sus datos antes de intentar iniciar sesión.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Acceso al Sistema</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 2em; background-color: #e0f2f7; display: flex; justify-content: center; align-items: center; min-height: 90vh; }
.card-login { background-color: white; padding: 2.5em; border-radius: 10px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); max-width: 450px; width: 100%; }
h1 { text-align: center; color: #0277bd; margin-bottom: 1.5em; }
.form-group { margin-bottom: 1.2em; }
.form-group label { display: block; margin-bottom: 0.5em; font-weight: bold; color: #333; }
.form-group input[type="text"], .form-group input[type="password"] { width: calc(100% - 22px); padding: 10px; border: 1px solid #b0bec5; border-radius: 5px; font-size: 1rem; }
.form-group input[type="checkbox"] { margin-right: 8px; }
.form-group .checkbox-options { display: flex; flex-wrap: wrap; gap: 15px; margin-top: 0.8em; }
.form-group .checkbox-options label { font-weight: normal; color: #555; }
button { background-color: #007bff; color: white; padding: 12px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 1.1rem; width: 100%; transition: background-color 0.3s ease; margin-top: 1.5em; }
button:hover { background-color: #0056b3; }
</style>
</head>
<body>
<div class="card-login">
<h1>Bienvenido, Inicie Sesión</h1>
<form action="${pageContext.request.contextPath}/autenticar" method="post">
<div class="form-group">
<label for="nombreDeUsuario">Nombre de Usuario:</label>
<input type="text" id="nombreDeUsuario" name="nombreDeUsuario" required>
</div>
<div class="form-group">
<label for="claveDeAcceso">Contraseña:</label>
<input type="password" id="claveDeAcceso" name="claveDeAcceso" required>
</div>
<div class="form-group">
<label>Seleccione sus Preferencias:</label>
<div class="checkbox-options">
<input type="checkbox" id="prefLibros" name="preferencias" value="Lectura"><label for="prefLibros">Lectura</label>
<input type="checkbox" id="prefCodificar" name="preferencias" value="Programacion"><label for="prefCodificar">Programación</label>
<input type="checkbox" id="prefPeliculas" name="preferencias" value="Cine"><label for="prefPeliculas">Cine</label>
<input type="checkbox" id="prefDeporte" name="preferencias" value="Deporte"><label for="prefDeporte">Deporte</label>
</div>
</div>
<button type="submit">Acceder</button>
</form>
</div>
</body>
</html>
Página de Confirmación de Acceso (confirmacion-acceso.jsp)
Esta página se mostrará al usuario una vez que el servlet haya procesado el inicio de sesión con éxito.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Acceso Confirmado</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 2em; background-color: #e6ffe6; text-align: center; display: flex; justify-content: center; align-items: center; min-height: 90vh; }
.success-card { background-color: white; padding: 2.5em; border-radius: 10px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); max-width: 450px; width: 100%; border-left: 5px solid #28a745; }
h1 { color: #28a745; margin-bottom: 0.8em; }
p { font-size: 1.1em; color: #444; }
</style>
</head>
<body>
<div class="success-card">
<h1>¡Inicio de Sesión Exitoso!</h1>
<p>Ha accedido al sistema correctamente. ¡Bienvenido!</p>
</div>
</body>
</html>
Configuración del Proyecto Maven
Para compilar y ejecutar esta aplicación web, se necesita un archivo pom.xml que defina las dependencias de la API de Servlets de Jakarta EE.
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>webapp-simple-auth</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<jakarta.servlet.api.version>5.0.0</jakarta.servlet.api.version> <!-- Servlet 5.0 para Jakarta EE 9 -->
<jakarta.servlet.jsp.api.version>3.0.0</jakarta.servlet.jsp.api.version> <!-- JSP 3.0 para Jakarta EE 9 -->
</properties>
<dependencies>
<!-- API de Servlets de Jakarta EE -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>${jakarta.servlet.api.version}</version>
<scope>provided</scope> <!-- Suministrado por el contenedor de servlets (ej. Tomcat) -->
</dependency>
<!-- Opcional: API de JSP de Jakarta EE si se utilizan explícitamente etiquetas en un IDE -->
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>${jakarta.servlet.jsp.api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Plugin para la compilación de código fuente Java -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Plugin para empaquetar el proyecto como un archivo WAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<!-- Si se usan anotaciones para servlets, web.xml puede ser opcional -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Aunque en este ejemplo se utiliza la anotación @WebServlet para el mapeo del servlet, también es posible configurar el servlet mediante el archivo web.xml. A continuación se muestra la configuración equivalente para web.xml, que puede ser utilizada si se prefiere un enfoque de despliegue descriptivo:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"> <!-- Usando la especificación Servlet 5.0 -->
<servlet>
<servlet-name>gestorAuth</servlet-name>
<servlet-class>com.example.webapp.GestorAutenticacionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gestorAuth</servlet-name>
<url-pattern>/autenticar</url-pattern>
</servlet-mapping>
</web-app>
Este sistema de ejemplo ilustra un flujo fundamental para la interacción de usuarios en una aplicación web: capturar datos a través de un formulario, procesarlos en un servlet y, finalmente, mostrar una página de confirmación al usuario.