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)
- POST – Enviamos el formulario desde persona-form.jsp a /persona?action=agregar
- Procesar – El servlet crea el PersonaVO, valida y llama a dao.agregar(...)
- Redirect – El servlet no muestra la vista; en su lugar redirige (HTTP 302/303) a /persona
- GET – El navegador sigue la redirección y hace GET a /persona
- 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