Back to results for “Design Patterns in Java”
Java › Design Patterns in Java

How would you use the Chain of Responsibility pattern to implement a request-processing pipeline (such as middleware-style validation/authentication/logging), and how does this relate conceptually to servlet filters or web framework middleware?

Advanced

Answer

Chain of Responsibility passes a request sequentially through a chain of independent handler objects, each deciding whether to process the request itself, pass it along to the next handler in the chain, or short-circuit the chain entirely (e.g., rejecting an unauthenticated request before it reaches business logic) -- this is conceptually exactly how servlet Filters, ASP.NET Core middleware, and similar web framework request pipelines work: each handler/filter/middleware component wraps and potentially short-circuits the remainder of the chain, letting cross-cutting concerns (auth, logging, rate limiting) be composed independently and reordered without modifying the core request-handling logic itself.
public abstract class Handler {
    protected Handler next;
    public Handler setNext(Handler next) { this.next = next; return next; }
    public abstract void handle(Request request);
}

class AuthHandler extends Handler {
    public void handle(Request request) {
        if (!request.isAuthenticated()) { throw new SecurityException("Unauthorized"); }
        if (next != null) next.handle(request);  // pass along the chain
    }
}

Handler chain = new AuthHandler();
chain.setNext(new LoggingHandler()).setNext(new BusinessLogicHandler());
chain.handle(incomingRequest);
Real-world example A custom request-processing pipeline (built without a full web framework) chains an AuthHandler, RateLimitHandler, and LoggingHandler together using Chain of Responsibility, mirroring exactly the same conceptual structure as servlet Filters or ASP.NET Core middleware, letting each concern be independently composed, reordered, or removed.

Common follow-ups: What's the difference between Chain of Responsibility and simply calling a sequence of methods directly, given both process a request through multiple steps?;How would you make the chain configuration itself more flexible/dynamic (e.g., loaded from configuration rather than hardcoded)?