@FunctionalInterface public interface Handler
Context
.
Handlers are the key component of Ratpack applications. A handler either generate a response, or delegate to another handler in some way.
Handlers are expected to be asynchronous.
That is, there is no expectation that the handler is “finished” when its handle(Context)
method returns.
This facilitates the use of non blocking IO without needing to enter some kind of special mode.
An implication is that handlers must ensure that they either send a response or delegate to another handler.
Handlers are always part of a pipeline structure.
The Context
that the handler operates on provides the Context.next()
method that passes control to the next handler in the pipeline.
The last handler in the pipeline is always that generates a 404
client error.
Handlers can themselves insert other handlers into the pipeline, using the Context.insert(Handler...)
family of methods.
import ratpack.handling.*; // A responder may just return a response to the client… class SimpleHandler implements Handler { void handle(Context exchange) { exchange.getResponse().send("Hello World!"); } } // A responder may add a response header, before delegating to the next in the pipeline… class DecoratingHandler implements Handler { void handle(Context exchange) { exchange.getResponse().getHeaders().set("Cache-Control", "no-cache"); exchange.next(); } } // Or a handler may conditionally respond… class ConditionalHandler implements Handler { void handle(Context exchange) { if (exchange.getRequest().getPath().equals("foo")) { exchange.getResponse().send("Hello World!"); } else { exchange.next(); } } } // A handler does not need to participate in the response, but can instead "route" the exchange to different handlers… class RoutingHandler implements Handler { private final Handler[] fooHandlers; public RoutingHandler(Handler... fooHandlers) { this.fooHandlers = fooHandlers; } void handle(Context exchange) { if (exchange.getRequest().getPath().startsWith("foo/")) { exchange.insert(fooHandlers); } else { exchange.next(); } } } // It can sometimes be appropriate to directly delegate to a handler, instead of using exchange.insert() … class FilteringHandler implements Handler { private final Handler nestedHandler; public FilteringHandler(Handler nestedHandler) { this.nestedHandler = nestedHandler; } void handle(Context exchange) { if (exchange.getRequest().getPath().startsWith("foo/")) { nestedHandler.handle(exchange); } else { exchange.next(); } } }
Modifier and Type | Method and Description |
---|---|
void |
handle(Context context)
Handles the context.
|
@NonBlocking void handle(Context context) throws Exception
context
- The context to handleException
- if anything goes wrong (exception will be implicitly passed to the context's Context.error(Throwable)
method)