喷雾中的拦截器/过滤器

Bru*_*owe 2 scala spray

我正在忙着将我们的Spring/Groovy应用程序之一迁移到Spray/Scala.我对Spray很新,所以如果这是一个初学者问题,请原谅我.

目标是模拟我们的日志记录拦截器,它记录每个请求/响应的各种数据.在这部分代码中有很多逻辑,所以它不是一个简单的日志行.此外,我想用这个逻辑包装所有请求.

现有的Groovy/Spring拦截器:

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler {
  //do some logging logic
}


void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
  //do some more logging logic
}
Run Code Online (Sandbox Code Playgroud)

我的Scala演员看起来像这样

class BootServiceActor extends Actor with ViewingController with LazyLogging with ViewingWire {

def actorRefFactory = context

implicit val ctx = context.dispatcher

def receive = runRoute(route)(exceptionHandler, RejectionHandler.Default, context,
  RoutingSettings.default, LoggingContext.fromActorRefFactory)
}
Run Code Online (Sandbox Code Playgroud)

lmm*_*lmm 5

Spray/Scala的一大卖点是你可以避免像拦截器那样的"魔法",隐形之物.您可以通过使用类型和/或指令来实现相同的功能,但是您所做的一切在代码中都可见,并且由于类型系统,因此可以重构.例如,您可以使用scalaz Writer来累积与特定请求关联的日志消息,然后定义Marshaller[Writer[MyLogStructure, A]]为任何A具有现有编组器的日志消息提供的"元编组器" ,并在正确的结构中写入该特定请求的所有日志.如果您愿意,我很乐意详细介绍这种方法.

"预处理"部分最好由简单处理Directive; 因为Spray是反应性的和异步的,所以并不存在配对"前后"处理的概念.相反,您对请求执行某些操作并将其交给下一个处理步骤,最终将发送响应.如果您需要从预手柄通过传递一些"背景"的手柄后,再次这可能与"上下文类型"(我试图避免说出可怕的m字)最喜欢做State.