馃И Aprendiendo el patr贸n MVC cl谩sico con Java: todo en un solo flujo


Cuando est谩s empezando con el patr贸n MVC cl谩sico en Java, lo m谩s importante no es hacer una arquitectura perfecta, sino entender bien c贸mo se comunican las partes: el Servlet (controlador), el modelo de datos y el acceso a base de datos.

Por eso, en esta primera versi贸n uso un DAO concreto sin interfaz, para que el flujo sea f谩cil de seguir. Luego, m谩s adelante, podr茅 abstraerlo con una interfaz, aplicar SOLID y hacer mi c贸digo m谩s flexible.


馃攳 ¿Qu茅 es MVC cl谩sico?

  • Modelo: representa los datos, como un Usuario.

  • Vista: p谩gina JSP que muestra los datos.

  • Controlador: un HttpServlet que act煤a como puente entre la petici贸n y la l贸gica.

Estructura usada

com.miapp.model.Usuario           ← Modelo (POJO)
com.miapp.dao.UsuarioDAO          ← Clase DAO concreta (sin interfaz)
com.miapp.service.UsuarioService  ← L贸gica de negocio
com.miapp.web.UsuarioServlet      ← Servlet controlador

Clase Modelo: Usuario.java

package com.miapp.model;

public class Usuario {
    private int id;
    private String nombre;
    private String email;

    public Usuario(int id, String nombre, String email) {
        this.id = id;
        this.nombre = nombre;
        this.email = email;
    }

    // Getters
    public int getId() { return id; }
    public String getNombre() { return nombre; }
    public String getEmail() { return email; }
}

Clase DAO: UsuarioDAO.java

package com.miapp.dao;

import com.miapp.model.Usuario;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class UsuarioDAO {

    private Connection abrirConexion() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/miapp", "usuario", "clave");
    }

    public Usuario obtenerPorId(int id) {
        String sql = "SELECT * FROM usuarios WHERE id = ?";
        try (Connection conn = abrirConexion();
             PreparedStatement ps = conn.prepareStatement(sql)) {

            ps.setInt(1, id);
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    return new Usuario(rs.getInt("id"), rs.getString("nombre"), rs.getString("email"));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public List<Usuario> listarTodos() {
        List<Usuario> usuarios = new ArrayList<>();
        String sql = "SELECT * FROM usuarios";
        try (Connection conn = abrirConexion();
             PreparedStatement ps = conn.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {

            while (rs.next()) {
                usuarios.add(new Usuario(rs.getInt("id"), rs.getString("nombre"), rs.getString("email")));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return usuarios;
    }
}

Capa de Servicio: UsuarioService.java

package com.miapp.service;

import com.miapp.dao.UsuarioDAO;
import com.miapp.model.Usuario;
import java.util.List;

public class UsuarioService {
    private final UsuarioDAO usuarioDAO = new UsuarioDAO();

    public Usuario obtenerPorId(int id) {
        return usuarioDAO.obtenerPorId(id);
    }

    public List<Usuario> listarTodos() {
        return usuarioDAO.listarTodos();
    }
}

Servlet Constrolador: UsuarioServlet.java

package com.miapp.web;

import com.miapp.model.Usuario;
import com.miapp.service.UsuarioService;
import com.google.gson.Gson;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/usuario")
public class UsuarioServlet extends HttpServlet {

    private final UsuarioService usuarioService = new UsuarioService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String idParam = req.getParameter("id");
        if (idParam == null) {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Falta par谩metro id");
            return;
        }

        int id = Integer.parseInt(idParam);
        Usuario usuario = usuarioService.obtenerPorId(id);

        if (usuario == null) {
            resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Usuario no encontrado");
            return;
        }

        resp.setContentType("application/json;charset=UTF-8");
        resp.getWriter().write(new Gson().toJson(usuario));
    }
}

¿Por qu茅 empiezo as铆?

Porque este estilo me ayuda a entender c贸mo viajan los datos desde la petici贸n HTTP, pasando por el servicio, hasta la base de datos y de vuelta a la vista o JSON.


馃洜 ¿Y luego?

M谩s adelante, para hacer el c贸digo m谩s mantenible, podr茅:

  • Separar el UsuarioDAO en una interfaz y una implementaci贸n.

  • Usar inyecci贸n de dependencias con Spring.

  • Aplicar principios SOLID m谩s estrictamente.

  • Escribir pruebas unitarias usando mocks del DAO.


馃 Conclusi贸n

Aprender MVC cl谩sico en Java de forma sencilla y sin tantas capas es 煤til para entender el flujo. Despu茅s se mejora, pero primero se comprende.

Comentarios

Entradas populares de este blog

Configurando Servlets y JSP en Jetty

Firma de un Documento XML con Certificado Digital en Java para Uso Tributario en Chile

RESOLUCION SET BASICO DE FACTURA ELECTR脫NICA SII