public interface Context extends Registry
Handler
invocation.
It provides:
request
and response
next()
and insert(ratpack.handling.Handler...)
family of methods)
A context is also a Registry
of objects.
Arbitrary objects can be "pushed" into the context for use by downstream handlers.
There are some significant contextual objects that drive key infrastructure.
For example, error handling is based on informing the contextual ServerErrorHandler
of exceptions.
The error handling strategy for an application can be changed by pushing a new implementation of this interface into the context that is used downstream.
See insert(Handler...)
for more on how to do this.
There is also a set of default objects that are made available via the Ratpack infrastructure:
LaunchConfig
FileSystemBinding
that is the application LaunchConfig.getBaseDir()
MimeTypes
implementationServerErrorHandler
ClientErrorHandler
FileRenderer
BindAddress
PublicAddress
Redirector
Modifier and Type | Method and Description |
---|---|
<T> SuccessOrErrorPromise<T> |
background(Callable<T> backgroundOperation)
Perform a blocking operation, off the request thread.
|
void |
clientError(int statusCode)
Forwards the error to the
ClientErrorHandler in this service. |
void |
error(Exception exception)
Forwards the exception to the
ServerErrorHandler in this service. |
Path |
file(String path)
Gets the file relative to the contextual
FileSystemBinding . |
PathTokens |
getAllPathTokens()
The contextual path tokens of the current
PathBinding . |
Background |
getBackground()
An object to be used when executing blocking IO, or long operations.
|
BindAddress |
getBindAddress()
The address that this request was received on.
|
ByContentHandler |
getByContent()
A buildable handler useful for performing content negotiation.
|
ByMethodHandler |
getByMethod()
A buildable handler for conditional processing based on the HTTP request method.
|
Context |
getContext()
Returns this.
|
DirectChannelAccess |
getDirectChannelAccess()
Provides direct access to the backing Netty channel.
|
Foreground |
getForeground()
The application foreground.
|
PathTokens |
getPathTokens()
The contextual path tokens of the current
PathBinding . |
Request |
getRequest()
The HTTP request.
|
Response |
getResponse()
The HTTP response.
|
void |
insert(Handler... handlers)
Inserts some handlers into the pipeline, then delegates to the first.
|
void |
insert(Registry registry,
Handler... handlers)
Inserts some handlers into the pipeline to execute with the given registry, then delegates to the first.
|
void |
lastModified(Date date,
Runnable runnable)
Convenience method for handling last-modified based HTTP caching.
|
void |
next()
Delegate handling to the next handler in line.
|
void |
next(Registry registry)
Invokes the next handler, after adding the given registry.
|
void |
onClose(Action<? super RequestOutcome> onClose)
Registers a callback to be notified when the request for this context is “closed” (i.e.
|
<T> T |
parse(Class<T> type)
Shorthand for no option parses.
|
<T> T |
parse(Parse<T> parse)
Parses the request body into an object.
|
void |
redirect(int code,
String location)
Sends a redirect response location URL and status code (which should be in the 3xx range).
|
void |
redirect(String location)
Sends a temporary redirect response (i.e.
|
void |
render(Object object)
Render the given object, using the rendering framework.
|
void |
respond(Handler handler)
Convenience method for delegating to a single handler.
|
<T> ResultAction<T> |
resultAction(Action<T> action)
Creates a result action that uses the contextual error handler if the result is failure.
|
void |
withErrorHandling(Runnable runnable)
Executes the given runnable in a try/catch, where exceptions are given to
error(Exception) . |
Context getContext()
Request getRequest()
Response getResponse()
@NonBlocking void next()
The request and response of this object should not be accessed after this method is called.
@NonBlocking void next(Registry registry)
The given registry is appended to the existing. This means that it can shadow objects previously available.
import ratpack.handling.Handler; import ratpack.handling.Handlers; import ratpack.handling.Chain; import ratpack.handling.ChainAction; import ratpack.handling.Context; import ratpack.launch.HandlerFactory; import ratpack.launch.LaunchConfig; import ratpack.launch.LaunchConfigBuilder; import ratpack.util.Factory; import static ratpack.registry.Registries.registry; public interface SomeThing {} public class SomeThingImpl implements SomeThing {} public class UpstreamHandler implements Handler { public void handle(Context context) { context.next(registry(SomeThing.class, new SomeThingImpl())); } } public class DownstreamHandler implements Handler { public void handle(Context context) { SomeThing someThing = context.get(SomeThing.class); // instance provided upstream assert someThing instanceof SomeThingImpl; // … } } LaunchConfigBuilder.baseDir(new File("base")).build(new HandlerFactory() { public Handler create(LaunchConfig launchConfig) { return Handlers.chain(launchConfig, new ChainAction() { public void execute(Chain chain) { chain.handler(new UpstreamHandler()); chain.handler(new DownstreamHandler()); } }); } });
registry
- The registry to make available for subsequent handlers.@NonBlocking void insert(Handler... handlers)
The request and response of this object should not be accessed after this method is called.
handlers
- The handlers to insert.@NonBlocking void insert(Registry registry, Handler... handlers)
The given registry is only applicable to the inserted handlers.
Almost always, the registry should be a super set of the current registry.
handlers
- The handlers to insertregistry
- The registry for the inserted handlers@NonBlocking void respond(Handler handler)
Designed to be used in conjunction with the getByMethod()
and getByContent()
methods.
handler
- The handler to invokeByContentHandler
,
ByMethodHandler
ByMethodHandler getByMethod()
ByContentHandler getByContent()
@NonBlocking void error(Exception exception) throws NotInRegistryException
ServerErrorHandler
in this service.
The default configuration of Ratpack includes a ServerErrorHandler
in all contexts.
A NotInRegistryException
will only be thrown if a very custom service setup is being used.
exception
- The exception that occurredNotInRegistryException
- if no ServerErrorHandler
can be found in the service@NonBlocking void clientError(int statusCode) throws NotInRegistryException
ClientErrorHandler
in this service.
The default configuration of Ratpack includes a ClientErrorHandler
in all contexts.
A NotInRegistryException
will only be thrown if a very custom service setup is being used.statusCode
- The 4xx range status code that indicates the error typeNotInRegistryException
- if no ClientErrorHandler
can be found in the servicevoid withErrorHandling(Runnable runnable)
error(Exception)
.
This can be used by handlers when they are jumping off thread. Exceptions raised on the thread that called the handler's handle will always be caught. If the handler “moves” to another thread, it should call this method no the new thread to ensure that any thrown exceptions are caught and forwarded appropriately.
runnable
- The code to surround with error handling<T> ResultAction<T> resultAction(Action<T> action)
The given action is invoked if the result is successful.
T
- The type of the successful result valueaction
- The action to invoke on a successful result.Result<T>
PathTokens getPathTokens() throws NotInRegistryException
PathBinding
.
Shorthand for get(PathBinding.class).getPathTokens()
.
PathBinding
.NotInRegistryException
- if there is no PathBinding
in the current servicePathTokens getAllPathTokens() throws NotInRegistryException
PathBinding
.
Shorthand for get(PathBinding.class).getAllPathTokens()
.
PathBinding
.NotInRegistryException
- if there is no PathBinding
in the current servicePath file(String path) throws NotInRegistryException
FileSystemBinding
.
Shorthand for get(FileSystemBinding.class).file(path)
.
The default configuration of Ratpack includes a FileSystemBinding
in all contexts.
A NotInRegistryException
will only be thrown if a very custom service setup is being used.
path
- The path to pass to the FileSystemBinding.file(String)
method.FileSystemBinding
NotInRegistryException
- if there is no FileSystemBinding
in the current service@NonBlocking void render(Object object)
The first Renderer
, that is able to render the given object will be delegated to.
If the given argument is null
, this method will have the same effect as clientError(404)
.
If no renderer can be found for the given type, a NoSuchRendererException
will be given to error(Exception)
.
If a renderer throws an exception during its execution it will be wrapped in a RendererException
and given to error(Exception)
.
Ratpack has built in support for rendering the following types:
Path
(see FileRenderer
)CharSequence
(see CharSequenceRenderer
)
See Renderer
for more on how to contribute to the rendering framework.
object
- The object to renderBackground getBackground()
background(java.util.concurrent.Callable)
Foreground getForeground()
Foreground
<T> SuccessOrErrorPromise<T> background(Callable<T> backgroundOperation)
Ratpack apps typically do not use a large thread pool for handling requests. By default there is about one thread per core.
This means that blocking IO operations cannot be done on the thread invokes a handler. Background IO operations must be
offloaded in order to free the request handling thread to handle other requests while the IO operation is performed.
The Background
object makes it easy to do this.
A callable is submitted to the Background.exec(Callable)
method. The implementation of this callable can background
as it will be executed on a non request handling thread. It should do not much more than initiate a blocking IO operation and return the result.
However, the callable is not executed immediately. The return value of Background.exec(Callable)
must be used to specify
how to proceed after the blocking operation. The then()
method must be called for the work to be performed.
import ratpack.handling.Handler; import ratpack.handling.Context; import ratpack.util.Action; import java.util.concurrent.Callable; class MyHandler implements Handler { void handle(final Context context) { context.background(new Callable<String>() { public String call() { // perform some kind of blocking IO in here, such as accessing a database return "foo"; } }).then(new Action<String>() { public void execute(String result) { context.getResponse().send(result); } }); } }
Unless otherwise specified, any exceptions that are raised during the blocking operation callable are forwarded
to the error(Exception)
method of the current context.
Similarly, errors that occur during the result handler are forwarded.
To use a custom error handling strategy, use the SuccessOrErrorPromise.onError(Action)
method
of the return of Background.exec(Callable)
.
Example usage:
import ratpack.handling.Handler; import ratpack.handling.Context; import ratpack.util.Action; import java.util.concurrent.Callable; class MyHandler implements Handler { void handle(final Context context) { context.background(new Callable<String>() { public String call() { // perform some kind of blocking IO in here, such as accessing a database return "foo"; } }).onError(new Action<Exception>() { public void execute(Exception exception) { // do something with the exception } }).then(new Action<String>() { public void execute(String result) { context.getResponse().send(result); } }); } }
T
- The type of object returned by the background operationbackgroundOperation
- The blocking operation to perform off of the request threadgetBackground()
void redirect(String location) throws NotInRegistryException
location
- the redirect location URLNotInRegistryException
- if there is no Redirector
in the current service but one is provided by defaultvoid redirect(int code, String location) throws NotInRegistryException
code
- The status code of the redirectlocation
- the redirect location URLNotInRegistryException
- if there is no Redirector
in the current service but one is provided by default@NonBlocking void lastModified(Date date, Runnable runnable)
The given date is the "last modified" value of the response. If the client sent an "If-Modified-Since" header that is of equal or greater value than date, a 304 will be returned to the client. Otherwise, the given runnable will be executed (it should send a response) and the "Last-Modified" header will be set by this method.
date
- The effective last modified date of the responserunnable
- The response sending action if the response needs to be sentBindAddress getBindAddress()
<T> T parse(Parse<T> parse) throws NoSuchParserException, ParserException
How to parse the request is controlled by the given Parse
object.
Parser resolution happens as follows:
parsers
are retrieved from the context registry (i.e. getAll(Parser.class)
);getAll()
) for compatibility with the given parse
object and the current request content type;Parser.parse(Context, ratpack.http.TypedData, ratpack.parse.Parse)
method is called, of which the return value is returned by this method;NoSuchParserException
will be thrown.A parser is compatible if all of the following hold true:
Parser.getContentType()
is exactly equal to getRequest().getBody().getContentType().getType()
parse
object is an instanceof
its Parser.getParseType()
Parser.getParsedType()
is Class.isAssignableFrom(Class)
the Parse.getType()
of the parse
object
If the request has no declared content type, text/plain
will be assumed.
Ratpack core provides implicit parsers for the following parse and content types:
Form
import ratpack.handling.Handler; import ratpack.handling.Context; import ratpack.form.Form; import static ratpack.parse.NoOptParse.to; public class FormHandler implements Handler { public void handle(Context context) { Form form = context.parse(to(Form.class)); context.render(form.get("someFormParam")); } }
T
- The type of object the request is parsed intoparse
- The specification of how to parse the requestNoSuchParserException
- if no suitable parser could be found in the registryParserException
- if a suitable parser was found, but it threw an exception while parsingParser
<T> T parse(Class<T> type) throws NoSuchParserException, ParserException
The code sample is functionally identical to the sample given for the parse(ratpack.parse.Parse)
variant…
import ratpack.handling.Handler; import ratpack.handling.Context; import ratpack.form.Form; public class FormHandler implements Handler { public void handle(Context context) { Form form = context.parse(Form.class); context.render(form.get("someFormParam")); } }
That is, it is effectively a convenient wrapper around NoOptParse.to(Class)
.
T
- the type to parse totype
- the type to parse toNoSuchParserException
- if no suitable parser could be found in the registryParserException
- if a suitable parser was found, but it threw an exception while parsingvoid onClose(Action<? super RequestOutcome> onClose)
onClose
- A notification callbackDirectChannelAccess getDirectChannelAccess()
General only useful for low level extensions. Avoid if possible.