Anexo Patron PRG - eliizquierdo/material_programacion_avanzada2026 GitHub Wiki

Patrón PRG: ¿qué problema resuelve?

Cuando enviamos un formulario con POST y el servidor responde mostrando directamente una vista (por ejemplo, con forward), si luego actualizamos (F5) o volvemos con el navegador, el navegador intentará reenviar el POST. Eso provoca duplicados (dos inserciones, dos compras, etc.) y una mala experiencia.

Con PRG, vamos a procesar el POST y redirigir a una URL de tipo GET. Así, si actualizamos la página, el navegador solo repetirá el GET, no el POST. Se termina el problema del reenvío.

Flujo PRG paso a paso (nuestro caso)

  1. POST – Enviamos el formulario desde persona-form.jsp a /persona?action=agregar
  2. Procesar – El servlet crea el PersonaVO, valida y llama a dao.agregar(...)
  3. Redirect – El servlet no muestra la vista; en su lugar redirige (HTTP 302/303) a /persona
  4. GET – El navegador sigue la redirección y hace GET a /persona
  5. Listar – El servlet atiende el GET, pide dao.getLista() y hace forward a persona-lista.jsp

Diagrama rápido:

Formulario (POST) ──► Servlet doPost ──► [agrega en DAO]
                              │
                              └── sendRedirect("/persona") ──► GET /persona ──► lista.jsp

¿Por qué nos conviene?

  • Evitamos reenvío de formularios al refrescar (adiós duplicados)
  • Mejor UX: la URL final es "navegable" y marcable (bookmark)
  • Claridad: el POST queda solo para "cambiar estado", el GET solo para "mostrar"
  • Arquitectura limpia: separamos "proceso" de "presentación final"

forward vs sendRedirect

forward() sendRedirect()
¿Quién genera la respuesta? Otro recurso interno (JSP) El navegador hace un nuevo GET
¿La URL cambia en el navegador? No Sí
¿Se conservan los atributos? Sí (setAttribute) No (nueva request)
¿Cuándo usarlo? Para mostrar vistas (lista, formulario) Después de un POST (PRG)
// Usar forward para mostrar una vista:
request.getRequestDispatcher("/WEB-INF/vista/persona-lista.jsp").forward(request, response);

// Usar sendRedirect después de insertar/actualizar/eliminar:
response.sendRedirect(request.getContextPath() + "/persona");

Resumen visual

¿Estoy MOSTRANDO datos?   →  usa forward()       → el JSP genera el HTML
¿Estoy MODIFICANDO datos? →  usa sendRedirect()   → PRG, evita doble envío

← Resumen completo de Servlets · 🏠 Inicio · Transacciones →