我的服务器应用程序使用 Scalatra、json4s 和 Akka。
它收到的大多数请求都是 POST,它们会立即以固定的响应返回给客户端。实际响应异步发送到客户端的服务器套接字。为此,我需要getRemoteAddr
从 http 请求。我正在尝试使用以下代码:
case class MyJsonParams(foo:String, bar:Int)
class MyServices extends ScalatraServlet {
implicit val formats = DefaultFormats
post("/test") {
withJsonFuture[MyJsonParams]{ params =>
// code that calls request.getRemoteAddr goes here
// sometimes request is null and I get an exception
println(request)
}
}
def withJsonFuture[A](closure: A => Unit)(implicit mf: Manifest[A]) = {
contentType = "text/json"
val params:A = parse(request.body).extract[A]
future{
closure(params)
}
Ok("""{"result":"OK"}""")
}
}
该withJsonFuture
函数的目的是将一些样板从我的路由处理中移出。
这有时有效(为 打印一个非空值request
),有时request
为空,我觉得这很令人费解。我怀疑我必须request
在我的未来“关闭”。但是,当没有其他请求正在进行时,受控测试场景也会发生错误。我会想象request
是不可变的(也许我错了?)
为了解决这个问题,我将代码更改为以下内容:
case class MyJsonParams(foo:String, bar:Int)
class MyServices extends ScalatraServlet {
implicit val formats = DefaultFormats
post("/test") {
withJsonFuture[MyJsonParams]{ (addr, params) =>
println(addr)
}
}
def withJsonFuture[A](closure: (String, A) => Unit)(implicit mf: Manifest[A]) = {
contentType = "text/json"
val addr = request.getRemoteAddr()
val params:A = parse(request.body).extract[A]
future{
closure(addr, params)
}
Ok("""{"result":"OK"}""")
}
}
这似乎有效。但是,我真的不知道它是否仍然包含任何可能导致未来错误的与并发相关的不良编程实践(“未来”在其最常见的意义上意味着 = 未来 :)。