我想从Json响应返回字符串
对不起,我是Scala的新手。我已经阅读了Futures和Akka的相关内容,但是我仍然无法为我的方法返回字符串 我有一个方法getAuthString,它应该返回身份验证字符串(或令牌)。 我使用了spray Jsonsupport,可以打印结果我想从Json响应返回字符串,json,scala,spray-client,Json,Scala,Spray Client,对不起,我是Scala的新手。我已经阅读了Futures和Akka的相关内容,但是我仍然无法为我的方法返回字符串 我有一个方法getAuthString,它应该返回身份验证字符串(或令牌)。 我使用了spray Jsonsupport,可以打印结果 def getToken(url: String, username: String , password: String) = Future[String]{ import MyJsonProtocol._ import spray.httpx.
def getToken(url: String, username: String , password: String) = Future[String]{
import MyJsonProtocol._
import spray.httpx.SprayJsonSupport._
val pipeline: HttpRequest => Future[AuthTokenResult[Entry]] = (addCredentials(BasicHttpCredentials(username, password))
~> sendReceive
~> unmarshal[AuthTokenResult[Entry]]
)
val myfutureResponse: Future[AuthTokenResult[Entry]] = pipeline(Get(url))
myfutureResponse onComplete {
case Success(AuthTokenResult(Entry(Content(authString)):: _)) => println(authString)
case Failure(error) => println("An error has occured: " + error.getMessage)
}
这将解组json并打印所需的authString。然而,印刷对我没有好处。我知道一个完整的返回单元。我想返回authString,这样我就可以在其他地方与另一个请求一起使用它。我想我将不得不使用平面图或地图,但我不知道如何使用。我需要我的方法返回authString或error 你不想返回一个
字符串,你想返回一个未来的[String]
——一旦某个东西是异步的,使它不异步的唯一方法就是阻塞,这(通常)是一种浪费,使得整个异步变得毫无意义
我也不知道你为什么要把整个事情包装在一个未来
中——琐碎的计算可以自己进行,把它们强制放到一个单独的线程上没有什么价值。所以你想要的是:
def getToken(url: String, ...): Future[String] = {
...
val myFutureResponse: Future[AuthTokenResult[Entry]] = ...
myFutureResponse map {
case AuthTokenResult(Entry(Content(authString))::_) => authString
}
}
因此,您可以使用map
通过计算将一个Future
转换为另一个Future
。这将“传递”错误,但如果要以特定方式处理这些错误,可以使用类似于recover
或recoverWith
的方法
然后,当您想在喷洒路线中使用Future[String]
时,可以使用onSuccess
或onComplete
指令:
val myRoute = (path("/somewhere") & parameter("authData") {
authData =>
onSuccess(getToken(authData)) {
authToken =>
complete("Authed as " + authToken)
}
}
这将以适当的异步、反应式方式使用未来
,而不会阻塞。感谢@Imm的及时响应。你给了我足够多的建议,我很高兴你的回答,但是,请原谅我的无知。如果我使用路由方法,这意味着需要进行API调用/url/path+?authToken的所有代码都必须位于单个代码块中。为什么我不能使用Val mytoken=getToken(url,…)这样每当我需要发出API请求时,我就可以将令牌作为请求参数的一部分附加到我的url中。你说如果我这样做,这将是阻塞,问题是我最终将没有可重用的代码哦,我不知道你只是在使用spray客户端。您可以使用承诺来持有authToken
:val authToken=Promise[String]();authToken.completeWith(getToken())
然后在其他代码中使用authToken.future
。或者你可以找个演员。或者您的代码根本不需要异步,在这种情况下,您只需执行val authToken=wait.result(getToken(),30秒)
。在这种情况下,最好不要使用spray,因为它增加了高性能并行代码所需的复杂性,但简单的情况可以使用更简单的库。