Interface Handler
-
- All Known Subinterfaces:
RequestLogger
,RequestTimingHandler
- All Known Implementing Classes:
GroovyHandler
,HealthCheckHandler
,InjectionHandler
,MetricsPrometheusHandler
,MetricsWebsocketBroadcastHandler
,ResponseTimer
- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
@FunctionalInterface public interface Handler
A handler participates in the processing of a request/response pair, operating on aContext
.Handlers are the key component of Ratpack applications. A handler either generate a response, or delegate to another handler in some way.
Non blocking/Asynchronous
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.Handler pipeline
Handlers are always part of a pipeline structure. The
Context
that the handler operates on provides theContext.next()
method that passes control to the next handler in the pipeline. The last handler in the pipeline is always that generates a404
client error.Handlers can themselves insert other handlers into the pipeline, using the
Context.insert(Handler...)
family of methods.Examples
While there is no strict taxonomy of handlers, the following are indicative examples of common functions.import ratpack.core.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(); } } }
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description void
handle(Context ctx)
Handles the context.
-
-
-
Method Detail
-
handle
@NonBlocking void handle(Context ctx) throws Exception
Handles the context.- Parameters:
ctx
- The context to handle- Throws:
Exception
- if anything goes wrong (exception will be implicitly passed to the context'sContext.error(Throwable)
method)
-
-