Anexo Referencia JSP - eliizquierdo/material_programacion_avanzada2026 GitHub Wiki

Anexo — Referencia JSP del proyecto

Esta página es una referencia detallada de los patrones JSP usados en el proyecto CRUD del curso. Para los conceptos introductorios de JSP, ver ¿Qué es un archivo JSP?.


Configuración inicial (común en todos los JSP del proyecto)

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>

Acceso a datos del proyecto con EL

pageContext.request.contextPath

${pageContext.request.contextPath}   <!-- Obtiene la ruta base de la app -->

requestScope

${requestScope.personas}   <!-- Lista de PersonaVO enviada por el controlador -->
${requestScope.persona}    <!-- Objeto PersonaVO individual -->

💡 Si el atributo no coincide con ninguna variable EL implícita, también se puede acceder directamente por nombre: ${personas}, ${persona}. Usar requestScope. deja más claro de dónde viene el dato.


Patrones del proyecto por tipo de JSP

index.jsp

  • JSP básico con HTML estático
  • Uso de contextPath para navegación
  • Enlaces a las secciones del CRUD
<a href="${pageContext.request.contextPath}/persona?action=agregar">Agregar persona</a>
<a href="${pageContext.request.contextPath}/persona?action=listar">Ver personas</a>

persona-form.jsp (Agregar)

  • Formulario con campos vacíos
  • action="agregar" en campo hidden
  • Validaciones HTML5 (required)
<form action="${pageContext.request.contextPath}/persona" method="post">
    <input type="hidden" name="action" value="agregar" />
    <input type="text" name="nombre" required />
    <button type="submit">Guardar</button>
</form>

persona-editar.jsp (Editar)

  • Formulario con campos precargados desde ${persona}
  • action="editar" en campo hidden
  • Campo código en readonly
<form action="${pageContext.request.contextPath}/persona" method="post">
    <input type="hidden" name="action" value="editar" />
    <input type="number" name="codigo" value="${persona.codigo}" readonly required />
    <input type="text" name="nombre" value="${persona.nombre}" required />
    <button type="submit">Guardar cambios</button>
</form>

persona-lista.jsp (Listar)

  • Iteración con <c:forEach> sobre ${requestScope.personas}
  • EL para mostrar propiedades de cada PersonaVO
  • Formulario inline para eliminar
  • Manejo de lista vacía con <c:if>
<c:if test="${not empty requestScope.personas}">
    <table>
        <c:forEach var="p" items="${requestScope.personas}">
            <tr>
                <td>${p.codigo}</td>
                <td>${p.nombre}</td>
                <td>
                    <a href="${pageContext.request.contextPath}/persona?action=editar&codigo=${p.codigo}">Editar</a>
                    <form action="${pageContext.request.contextPath}/persona" method="post"
                          onsubmit="return confirm('¿Eliminar a ${p.nombre}?')">
                        <input type="hidden" name="action" value="eliminar" />
                        <input type="hidden" name="codigo" value="${p.codigo}" />
                        <button type="submit">Eliminar</button>
                    </form>
                </td>
            </tr>
        </c:forEach>
    </table>
</c:if>
<c:if test="${empty requestScope.personas}">
    <p>No hay personas registradas.</p>
</c:if>

Flujo de datos en el proyecto

PersonaControladorServlet
    → request.setAttribute("personas", listaPersonas)
    → request.setAttribute("persona", unaPersona)
         ↓
JSP con EL/JSTL
    → ${requestScope.personas} / ${persona}
    → <c:forEach>, <c:if>
         ↓
HTML generado → navegador del cliente

Buenas prácticas aplicadas en el proyecto

1. Codificación UTF-8

<%@ page contentType="text/html; charset=UTF-8" %>

2. URLs con contextPath

${pageContext.request.contextPath}/css/styles.css
${pageContext.request.contextPath}/persona?action=listar

3. Validación del lado cliente

<input type="text" name="nombre" required />
onsubmit="return confirm('¿Eliminar a ${p.nombre}?');"

4. Separación de responsabilidades

  • El JSP solo se ocupa de presentación, usando EL y JSTL
  • La lógica de negocio va en el controlador (Servlet)
  • Los datos llegan desde atributos del request (request.setAttribute)

5. Manejo de lista vacía

<c:if test="${not empty requestScope.personas}">
    <!-- mostrar tabla -->
</c:if>
<c:if test="${empty requestScope.personas}">
    <!-- mensaje de lista vacía -->
</c:if>

Errores comunes en el proyecto

❌ Olvidar declarar el taglib:

<c:forEach var="p" items="${personas}">   <!-- Error: c:forEach no reconocido -->

✅ Declarar el taglib al inicio del JSP:

<%@ taglib prefix="c" uri="jakarta.tags.core" %>

❌ URLs hardcodeadas:

<form action="/persona" method="post"> <!-- Error en producción -->

✅ URLs con contextPath:

<form action="${pageContext.request.contextPath}/persona" method="post">

❌ Olvidar agregar la dependencia JSTL en pom.xml:

<!-- sin esto, usar <c:forEach> o cualquier etiqueta JSTL genera error 500 -->
<dependency>
    <groupId>jakarta.servlet.jsp.jstl</groupId>
    <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
    <version>3.0.0</version>
</dependency>

✅ Agregar las dependencias JSTL en pom.xml antes de usar etiquetas <c:...>:

<dependency>
    <groupId>jakarta.servlet.jsp.jstl</groupId>
    <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
    <version>3.0.0</version>
</dependency>
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jakarta.servlet.jsp.jstl</artifactId>
    <version>3.0.1</version>
</dependency>

💡 Con EL no es necesario validar objetos nulos a mano: ${persona.nombre} no rompe la página si persona es null, simplemente no muestra nada.


📋 Palabras clave

JSP · JavaServer Pages · Expression Language · EL · ${variable} · JSTL · taglib · c:if · c:forEach · requestScope · PersonaVO · contextPath · Vista MVC · CRUD


← 🏠 Inicio · Ver introducción a JSP →

⚠️ **GitHub.com Fallback** ⚠️