A basic example of using Dispatch with Scalatra on Jetty 8.x / AsyncServlet 3.0. It took me a lot of time to connect the dots how to use Dispatch asynchronously and actually process the results (not simply return them) and I could not find examples how to use Scalatra with AsyncServlet either. So here it is for anyone who could find it useful and save themselves a few –or more– hours.

import _root_.akka.dispatch._
import _root_.akka.actor._
import org.scalatra._
import org.scalatra.akka.AkkaSupport
import dispatch._
get("/asynctest") {
// Get the AsyncContext -- or create one.
val asctx =
if (request.isAsyncStarted) request.getAsyncContext
else request.startAsync
// Execute the rest of the route in an Akka Future
val result = Future {
// Create a RequestBuilder to be used by Dispatch
val url = host("slashdot.org") <:< Map(
("Accept-Charset" -> "utf-8")
)
// Make the request, receive it as Bytes not to
// disturb binary results. Http returns a Promise
// to a result and execution moves along. More
// information on the concepts is provided on
// the Dispatch web site.
val response = dispatch.Http(url OK as.Bytes)
// Set up a handler for Dispatch' return. This
// is bound on the Promise created earlier.
response.onComplete { x =>
// Get a handle to the response and its
// output stream, we'll need this to write
// results as soon as we have them.
val res = asctx.getResponse
val os = res.getOutputStream
// 'x' is the response of the upstream web
// service
x match {
// An error occurred, the exception is
// sent to the client (of course you
// would prefer to handle this otherwise
// in real-world code)
case Left(exc) => {
os.print(exc.getMessage)
}
// Response was received with a 200 HTTP
// code, everything went fine. Data is
// written to the output stream as bytes,
// after having set the encoding to UTF-8.
case Right(output) => {
res.setCharacterEncoding("utf-8")
os.write(output)
}
}
// It is crucial to "complete" the Asynchronous
// Context, otherwise no response will be sent
// to the client.
asctx.complete
}
}
}

Big fat disclaimer: I’m fairly new to Scala/Scalatra (and the JVM for that matter), so if there are mistakes in this example –or improvements to make– let me know and I’ll correct them in the post.

Update:Ivan Porto Carrero of the Scalatra fame comments below on a much easier/concise way to achieve the same result (minor edits of my own in the code that follows but the point is the same). So it turns out you can call .complete directly on an Akka Promise, without a need to move the servlet’s asynchronous context around: