07 - Front Controller

Con servlets, cada ruta necesita su componente. Cuando el número de rutas crece, aparecen problemas: configuración repetida, lógica transversal duplicada (autenticación, mapeo de errores) y nomenclatura inconsistente. El patrón front controller concentra toda la entrada en un único punto que enruta cada petición al código que la procesa.

Sin front controller:

  /books       -> BookServlet
  /books/42    -> BookDetailServlet
  /authors     -> AuthorServlet
  /login       -> LoginServlet

Cada servlet repite: validación del token, parseo, traducción de errores.

Con front controller:

  /*           -> DispatcherServlet (único punto de entrada)
                  ├── valida el token (una vez)
                  ├── decide el controlador según la ruta
                  └── traduce los errores (una vez)

@WebServlet("/*")
public class DispatcherServlet extends HttpServlet {
    private final BookController bookController = new BookController();
    private final AuthorController authorController = new AuthorController();

    @Override
    protected void service(HttpServletRequest request,
                           HttpServletResponse response)
            throws IOException {
        String path = request.getRequestURI();      // /books/42
        String method = request.getMethod();        // GET

        if (path.startsWith("/books")) {
            bookController.handle(request, response);
        } else if (path.startsWith("/authors")) {
            authorController.handle(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        }
    }
}

public class BookController {
    public void handle(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        String method = request.getMethod();

        switch (method) {
            case "GET" -> find(request, response);
            case "POST" -> create(request, response);
            default -> response.sendError(405);
        }
    }

    private void find(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        String id = extractId(request.getRequestURI());   // /books/42 -> 42
        // delegar en el service, escribir la respuesta JSON
    }
}

Componente Responsabilidad
DispatcherServlet Punto de entrada único: filtra, enruta y traduce errores
BookController Gestiona las operaciones de un recurso según el método HTTP
Service La lógica (capas de la arquitectura por capas)
  • Punto único para lógica transversal: token, errores, registro.
  • Rutas expresivas: una convención única (/books, /books/42) en lugar de un servlet por cada caso.
  • Componentes por recurso (controllers) con responsabilidad clara.
  • Es exactamente la estructura que automatiza Spring MVC con su DispatcherServlet: por eso entenderlo aquí hace trivial entender Spring en 2.º.

ClienteDispatcherServletFiltro de tokensBookControllerServiceClienteDispatcherServlet(front controller)Filtro de tokensBookControllerServiceClienteDispatcherServlet(front controller)Filtro de tokensBookControllerServicepeticióntoken válido/books/42, GETfindById(42)BookJSONrespuesta

El front controller no sustituye a la arquitectura por capas: la completa. El dispatcher y los controladores son la capa de presentación; debajo siguen service y repositorio con sus responsabilidades.
  • clase/daw/si/2eval/frontcontroller.txt
  • Última modificación: 2026/10/12 13:03
  • por cesguiro