Clase AlumnoControladorServlet - eliizquierdo/material_programacion_avanzada2026 GitHub Wiki

📦 Proyecto: mini-crud-alumno-sql (Tema 4 — Herencia + MySQL) — ⬇️ Descargar ZIP · ☁️ Abrir en Codespace

El AlumnoControladorServlet es el Manejador HTTP principal para las operaciones CRUD de los alumnos. Sigue el patrón Model-View-Controller (MVC), delegando las operaciones de acceso a datos a AlumnoDAO.

1. Mapeo y Atributos

  • Mapeo: El controlador está mapeado a la URL /alumno (gracias a @WebServlet("/alumno")). Todas las peticiones a /aplicacion/alumno serán manejadas aquí.
  • DAO: Contiene una instancia final de private final AlumnoDAO dao = new AlumnoDAO(); para acceder a la base de datos.

2. Peticiones doGet() (Lectura y Presentación de Formularios) 📄

El método doGet() gestiona las peticiones que no modifican datos, sino que solicitan vistas (listados o formularios).

Action Recibida (GET) Propósito Método Llamado Vista Final
action=agregar Mostrar formulario de alta (Directo) /WEB-INF/vista/alumno-form.jsp
action=editar Cargar datos y mostrar formulario de edición mostrarEditar() /WEB-INF/vista/alumno-editar.jsp
Ninguna/Otra Listar todos los alumnos listar() /WEB-INF/vista/alumno-lista.jsp

💡 Nota: igual que en el controlador de Persona, la acción eliminar no se procesa en el doGet(). Eliminar modifica datos, así que siempre se envía por POST (desde un formulario) y termina con PRG. Así se evitan borrados accidentales al recargar la página o al compartir un enlace.

3. Peticiones doPost() (Escritura y Modificación de Datos) 💾

El método doPost() gestiona las peticiones que envían formularios y modifican el estado de los datos.

Action Recibida (POST) Propósito Método Llamado Patrón Aplicado
action=agregar Procesar la creación de un nuevo alumno agregar() PRG (Redirección a /alumno)
action=actualizar Procesar la modificación de un alumno existente actualizar() PRG (Redirección a /alumno)
action=eliminar Procesar la eliminación de un alumno eliminar() PRG (Redirección a /alumno)
Cualquier otra Petición desconocida (Directo) Redirige al listado

A continuación el Código del Servlet:

package controlador;

import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;

import modelo.dao.AlumnoDAO;
import modelo.vo.AlumnoVO;

@WebServlet("/alumno")
public class AlumnoControladorServlet extends HttpServlet {
    // DAO
    private final AlumnoDAO dao = new AlumnoDAO();

    // ======================== GET ========================
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        String action = request.getParameter("action");
        if (action == null) {
            action = ""; // evita NPE en switch
        }

        switch (action) {
            case "agregar": // mostrar formulario de alta (GET)
                request.getRequestDispatcher("/WEB-INF/vista/alumno-form.jsp").forward(request, response);
                break;

            case "editar": // cargar datos y mostrar formulario de edición (GET)
                mostrarEditar(request, response);
                break;

            default: // sin action o desconocida → listar
                listar(request, response);
                break;
        }
    }

    // ======================== POST ========================
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        String action = request.getParameter("action");
        if (action == null) {
            response.sendRedirect(request.getContextPath() + "/alumno");
            return;
        }

        switch (action) {
            case "agregar":
                agregar(request, response);
                break;

            case "actualizar": // Corresponde a la acción de editar por POST
                actualizar(request, response);
                break;

            case "eliminar": // eliminar por POST (formulario con confirm())
                eliminar(request, response);
                break;

            default:
                // Si la acción POST es desconocida, redirigir al listado principal
                response.sendRedirect(request.getContextPath() + "/alumno");
                break;
        }
    }

4. Métodos Auxiliares y Lógica Central ⚙️

4.1. listar(request, response)

Función: Obtiene la lista completa de alumnos desde el dao.

Flujo:

  • Llama a dao.listarAlumnos().
  • Guarda la lista en el atributo de solicitud (request.setAttribute("alumnos", ...)).
  • Hace forward a /WEB-INF/vista/alumno-lista.jsp para renderizar la tabla.
private void listar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            request.setAttribute("alumnos", dao.listarAlumnos());
        } catch (Exception e) {
            request.setAttribute("error", "Error al listar alumnos: " + e.getMessage());
            e.printStackTrace();
        }
        request.getRequestDispatcher("/WEB-INF/vista/alumno-lista.jsp").forward(request, response);
    }

4.2. agregar(request, response) (POST)

Función: Procesa los datos de alta de un nuevo alumno, validando que el código no esté duplicado (igual que hicimos en Validación de unicidad de código).

Flujo:

  • Recupera codigo, nombre y telefono de los parámetros.
  • Verifica con dao.obtenerAlumnoPorCodigo(codigo) si ya existe un alumno con ese código.
  • Si existe, guarda el mensaje de error y los datos ingresados, y reenvía al formulario (sin insertar nada).
  • Si es único, crea el AlumnoVO completo y llama a dao.agregarAlumno() (que maneja la transacción en las tablas personas y alumnos).
  • Si hay éxito, aplica el Patrón PRG (response.sendRedirect(...)).
  • Si el código no es un número válido, o si ocurre otro error (ej: fallo de conexión), se reenvía la vista de formulario con un mensaje de error.
private void agregar(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
    try {
        // 1. Recuperar TODOS los parámetros, incluyendo el código
        int codigo = Integer.parseInt(request.getParameter("codigo"));
        String nombre = request.getParameter("nombre");
        String telefono = request.getParameter("telefono");

        // 2. VERIFICACIÓN DE UNICIDAD USANDO EL MÉTODO EXISTENTE
        AlumnoVO alumnoExistente = dao.obtenerAlumnoPorCodigo(codigo);

        if (alumnoExistente != null) {
            // Si el código existe, preparar mensaje de error y volver al formulario
            request.setAttribute("error", "Error: El código de alumno " + codigo + " ya existe.");

            // Para mantener los datos ingresados
            request.setAttribute("alumno", new AlumnoVO(codigo, nombre, telefono));

            request.getRequestDispatcher("/WEB-INF/vista/alumno-form.jsp").forward(request, response);
            return; // Detener la ejecución, no se inserta
        }

        // 3. Si es único (alumnoExistente == null), proceder con la inserción
        AlumnoVO nuevoAlumno = new AlumnoVO(codigo, nombre, telefono);
        dao.agregarAlumno(nuevoAlumno);

        response.sendRedirect(request.getContextPath() + "/alumno"); // PRG

    } catch (NumberFormatException e) {
        // Manejar error si el código no es un número válido
        request.setAttribute("error", "El código debe ser un número válido.");
        request.getRequestDispatcher("/WEB-INF/vista/alumno-form.jsp").forward(request, response);

    } catch (Exception e) {
        // Manejar otros errores (DAO, conexión, etc.)
        System.err.println("ERROR al agregar alumno: " + e.getMessage());
        e.printStackTrace();
        request.setAttribute("error", "No se pudo guardar el alumno: " + e.getMessage());
        request.getRequestDispatcher("/WEB-INF/vista/alumno-form.jsp").forward(request, response);
    }
}

4.3. mostrarEditar(request, response) (GET)

Función: Carga los datos de un alumno específico para mostrarlos en el formulario de edición.

Flujo:

  • Lee el codigo (esperando el parámetro id) desde la URL.
  • Llama a dao.obtenerAlumnoPorCodigo(codigo).
  • Guarda el AlumnoVO encontrado en la solicitud (request.setAttribute("alumno", ...)).
  • Hace forward a /WEB-INF/vista/alumno-editar.jsp.
  private void mostrarEditar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            int codigo = Integer.parseInt(request.getParameter("id"));
            AlumnoVO alumno = dao.obtenerAlumnoPorCodigo(codigo);
            request.setAttribute("alumno", alumno);
            request.getRequestDispatcher("/WEB-INF/vista/alumno-editar.jsp").forward(request, response);
        } catch (Exception e) {
            System.err.println("ERROR al mostrar editar: " + e.getMessage());
            e.printStackTrace();
            request.setAttribute("error", "No se pudo cargar el alumno: " + e.getMessage());
            listar(request, response);
        }
    }

4.4. actualizar(request, response) (POST)

Función: Aplica los cambios a un alumno existente.

Flujo:

  • Recupera el codigo (obligatorio), nombre y telefono.
  • Crea un AlumnoVO completo.
  • Llama a dao.actualizarAlumno() (que maneja la transacción en las tablas personas y alumnos).
  • Aplica el Patrón PRG (response.sendRedirect(...)).
  • Si hay error, llama nuevamente a mostrarEditar() para volver al formulario con el error visible.
    private void actualizar(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        try {
            int codigo = Integer.parseInt(request.getParameter("codigo"));
            String nombre = request.getParameter("nombre");
            String telefono = request.getParameter("telefono");

            boolean exito = dao.actualizarAlumno(new AlumnoVO(codigo, nombre, telefono));

            response.sendRedirect(request.getContextPath() + "/alumno"); // PRG
        } catch (Exception e) {
            System.err.println("ERROR al actualizar alumno: " + e.getMessage());
            e.printStackTrace();
            request.setAttribute("error", "No se pudo actualizar el alumno: " + e.getMessage());
            // Intenta volver a la vista de edición si falla la actualización
            mostrarEditar(request, response);
        }
    }

4.5. eliminar(request, response) (POST)

Función: Procesa la baja lógica (o física) de un alumno.

Flujo:

  • Lee el codigo desde el campo oculto id del formulario.
  • Llama a dao.eliminarAlumno(codigo).
  • Aplica el Patrón PRG (response.sendRedirect(...)) para volver al listado.
   private void eliminar(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        try {
            int codigo = Integer.parseInt(request.getParameter("id"));
            dao.eliminarAlumno(codigo);
        } catch (Exception e) {
            System.err.println("ERROR al eliminar alumno: " + e.getMessage());
            e.printStackTrace();
            // (Opcional: se podría guardar un mensaje de error en la sesión
            // antes de redirigir, para mostrarlo en la lista)
        }
        response.sendRedirect(request.getContextPath() + "/alumno"); // PRG
    }

5. Aplicación del Patrón PRG (Post-Redirect-Get)

El patrón PRG se utiliza tras cada operación de modificación de datos (agregar, actualizar, eliminar) para mantener el estado de la aplicación consistente y evitar el reenvío accidental de formularios:

response.sendRedirect(request.getContextPath() + "/alumno"); // PRG → listar
Operación Método Redirección (PRG)
agregar doPost() (acción agregar) Sí
actualizar doPost() (acción actualizar) Sí
eliminar doPost() (acción eliminar) Sí

Continuemos con Clase del paquete VISTA


📋 Palabras clave

AlumnoControladorServlet · @WebServlet · doGet · doPost · switch · action · AlumnoDAO · AlumnoVO · PRG · sendRedirect · forward · Controlador MVC · agregar alumno · editar alumno


🧠 Autoevaluación — Herencia en Java y BD


← AlumnoVO y AlumnoDAO · 🏠 Inicio · Modificaciones a la VISTA →