Modificaciones VISTA Alumnos - eliizquierdo/material_programacion_avanzada2026 GitHub Wiki
📦 Proyecto:
mini-crud-alumno-sql(Tema 4 — Herencia + MySQL) — ⬇️ Descargar ZIP · ☁️ Abrir en Codespace
La capa Vista es responsable de la Presentación de la información y de la Interacción con el usuario, enviando peticiones al AlumnoControladorServlet.
Ahora en vez de persona-form.jsp, persona-editar.jsp y persona-lista.jsp vamos a tener analogamente alumno-form.jsp, alumno-editar.jsp y alumno-lista.jsp
Esta página es la puerta de entrada, mostrando las opciones principales.
| Elemento | Propósito | URL Generada |
|---|---|---|
| Directiva @page | Configura la codificación a UTF-8. | N/A |
${pageContext.request.contextPath} |
Expression Language (EL) para construir rutas relativas seguras. |
/mini-crud-alumno-sql (Ejemplo) |
| Botón "Agregar Alumnos" | Muestra el formulario vacío para dar de alta un alumno. | alumno?action=agregar |
| Botón "Listar Alumno" | Muestra la tabla con todos los alumnos. |
alumno?action=listar (o /alumno por defecto) |
🔑 Clave de la Vista: Se usa href="alumno?action=..." para invocar al AlumnoControladorServlet y delegarle la lógica de navegación o datos.
<%@ page contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>CRUD con herencia</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/styles.css" />
</head>
<body>
<div class="form-container">
<h1>Bienvenidos al CRUD de alumnos</h1>
<a class="btn" href="${pageContext.request.contextPath}/alumno?action=agregar"
>Agregar Alumnos</a
>
<a class="btn" href="${pageContext.request.contextPath}/alumno?action=listar"
>Listar Alumno</a
>
</div>
</body>
</html>
Esta página presenta el formulario para crear un nuevo alumno. Al igual que en persona-form.jsp, incluye manejo de errores con JSTL (por si el código ya existe).
El AlumnoControladorServlet recibe action=agregar (GET) y hace forward a esta vista.
| Componente | Código Clave | Propósito |
|---|---|---|
| Acción del Formulario | <form action="${pageContext.request.contextPath}/alumno" method="post"> |
POST al AlumnoControladorServlet. Esto dispara el doPost(). |
| Campo Oculto | <input type="hidden" name="action" value="agregar"> |
Le dice al doPost() del Servlet que debe ejecutar el método agregar(). |
| Mensaje de error | <c:if test="${requestScope.error != null}"> |
Muestra el error si el código ya existe (validación de unicidad, igual que en Persona). |
| Campos de Entrada |
name="codigo", name="nombre" y name="telefono"
|
Capturan los datos del nuevo alumno. El código se ingresa a mano, igual que en el resto del curso (no es autoincremental). |
| Botón Guardar | <button type="submit">Guardar</button> |
Envía la petición POST. El Servlet valida, procesa el alta y aplica el PRG. |
| Botón Volver | <a href="${pageContext.request.contextPath}/alumno">Volver</a> |
Hace un GET simple a /alumno para volver al listado. |
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Agregar Alumno</title>
<link
rel="stylesheet"
href="${pageContext.request.contextPath}/css/styles.css"
/>
</head>
<body>
<div class="form-container">
<h1>Agregar Alumno</h1>
<c:if test="${requestScope.error != null}">
<div
style="
color: red;
border: 1px solid red;
padding: 10px;
margin-bottom: 15px;
background-color: #ffe8e8;
"
>
<strong>Error:</strong> ${requestScope.error}
</div>
</c:if>
<form action="${pageContext.request.contextPath}/alumno" method="post">
<input type="hidden" name="action" value="agregar" />
<label>Código</label>
<input type="number" name="codigo" required value="${requestScope.alumno.codigo}" />
<label>Nombre</label>
<input type="text" name="nombre" required value="${requestScope.alumno.nombre}" />
<label>Teléfono</label>
<input type="text" name="telefono" required value="${requestScope.alumno.telefono}" />
<button class="btn" type="submit">Guardar</button>
<a
class="btn btn-secondary"
href="${pageContext.request.contextPath}/alumno"
>Volver</a
>
</form>
</div>
</body>
</html>
Esta es la vista central que muestra los datos y las acciones de manipulación.
- El Servlet recupera la lista:
List<AlumnoVO> listaAlumnos = dao.listarAlumnos(); - Guarda la lista en la solicitud:
request.setAttribute("alumnos", listaAlumnos); - El JSP recorre la lista con JSTL:
<c:forEach var="a" items="${requestScope.alumnos}">
El cuerpo de la tabla (<tbody>) itera sobre alumnos usando JSTL, sin código Java embebido:
<c:if test="${not empty requestScope.alumnos}">
<c:forEach var="a" items="${requestScope.alumnos}">
<tr>
<td>${a.codigo}</td>
<td>${a.nombre}</td>
<td>${a.telefono}</td>
<td class="actions">
<a href="${pageContext.request.contextPath}/alumno?action=editar&id=${a.codigo}">Editar</a>
<form action="${pageContext.request.contextPath}/alumno" method="post" style="display:inline;">
<input type="hidden" name="action" value="eliminar" />
<input type="hidden" name="id" value="${a.codigo}" />
<button type="submit" onclick="...">Eliminar</button>
</form>
</td>
</tr>
</c:forEach>
</c:if>| Acción | Tipo de Petición | Parámetros Clave | Flujo |
|---|---|---|---|
| Editar | GET | action=editar&id=8 |
Invoca a doGet() para que ejecute mostrarEditar(), buscando el alumno 8. |
| Eliminar | POST |
action=eliminar e id=8 (campos ocultos) |
Formulario con confirm(). Invoca a doPost() para que ejecute eliminar(). Luego aplica PRG. |
| Agregar Alumno | GET | action=agregar |
Vuelve a llamar al Servlet para mostrar alumno-form.jsp. |
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Listado de Alumnos</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/styles.css" />
</head>
<body>
<div class="page-container">
<h1>Listado de Alumnos</h1>
<div class="table-wrap">
<table class="table">
<thead>
<tr>
<th>Código</th>
<th>Nombre</th>
<th>Teléfono</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<c:if test="${not empty requestScope.alumnos}">
<c:forEach var="a" items="${requestScope.alumnos}">
<tr>
<td>${a.codigo}</td>
<td>${a.nombre}</td>
<td>${a.telefono}</td>
<td class="actions">
<a
class="btn btn-edit"
href="${pageContext.request.contextPath}/alumno?action=editar&id=${a.codigo}"
>Editar</a
>
<form
action="${pageContext.request.contextPath}/alumno"
method="post"
style="display: inline"
>
<input type="hidden" name="action" value="eliminar" />
<input type="hidden" name="id" value="${a.codigo}" />
<button
type="submit"
class="btn btn-danger"
onclick="return confirm('¿Eliminar alumno?');"
>
Eliminar
</button>
</form>
</td>
</tr>
</c:forEach>
</c:if>
<c:if test="${empty requestScope.alumnos}">
<tr>
<td colspan="4">No hay alumnos cargados.</td>
</tr>
</c:if>
</tbody>
</table>
</div>
<a class="btn" href="${pageContext.request.contextPath}/alumno?action=agregar"
>Agregar Alumno</a
>
</div>
</body>
</html>
Esta nueva vista es crucial y es donde se ven los datos cargados previamente.
- El usuario selecciona Editar en
alumno-lista.jsp. - El Servlet recibe
action=editar&id=X. - El método
mostrarEditar()busca elAlumnoVOy lo guarda como atributo:request.setAttribute("alumno", alumnoEncontrado);. - El Servlet hace forward a
alumno-editar.jsp.
-
Carga de datos: El JSP usa Expression Language (EL) para precargar los valores en los campos de entrada:
<input type="text" name="nombre" value="${requestScope.alumno.nombre}">
-
Acción Oculta: La acción del formulario se cambia a:
<input type="hidden" name="action" value="actualizar">
-
Campo codigo: Se marca como
readonlypara que el usuario no lo altere (pero sigue viajando en el formulario para que el Servlet sepa qué registro modificar).<input type="number" name="codigo" value="${requestScope.alumno.codigo}" readonly>
-
Botón Actualizar: Dispara el POST con
action=actualizar. El Servlet ejecutaactualizar(), que aplica la lógica de UPDATE y luego aplica el PRG.
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Editar Alumno</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/styles.css" />
</head>
<body>
<div class="form-container">
<h1>Editar Alumno</h1>
<c:if test="${requestScope.alumno == null}">
<div class="alert danger">No se encontró el alumno a editar.</div>
<a class="btn btn-secondary" href="${pageContext.request.contextPath}/alumno">Volver</a>
</c:if>
<c:if test="${requestScope.alumno != null}">
<!-- POST al Servlet con action=actualizar -->
<form action="${pageContext.request.contextPath}/alumno" method="post">
<input type="hidden" name="action" value="actualizar" />
<label>Código</label>
<input
type="number"
name="codigo"
value="${requestScope.alumno.codigo}"
readonly
/>
<label>Nombre</label>
<input
type="text"
name="nombre"
value="${requestScope.alumno.nombre}"
required
/>
<label>Teléfono</label>
<input
type="text"
name="telefono"
value="${requestScope.alumno.telefono}"
required
/>
<button class="btn" type="submit">Actualizar</button>
<a class="btn btn-secondary" href="${pageContext.request.contextPath}/alumno">Volver</a>
</form>
</c:if>
</div>
</body>
</html>Ahora que la capa Vista está clara, podemos proceder a analizar cómo el AlumnoControladorServlet gestiona estas peticiones (que ya hicimos en la respuesta anterior, pero enfocaremos los cambios clave si fuera necesario).
Continuemos con el Resumen
alumno-form.jsp · alumno-lista.jsp · alumno-editar.jsp · Vista MVC · JSP · teléfono · AlumnoVO · Expression Language · EL · JSTL · c:forEach · c:if · precarga de datos · tabla · formulario
🧠 Autoevaluación — Herencia en Java y BD
