我的服务的所有API调用都是HTTP POST,参数在多部分正文中传递.目前我的身份验证看起来像这样
formField("token".as[String]) { token =>
authorize(isAuthorized(token)) {
.... my other routes here
}
}
Run Code Online (Sandbox Code Playgroud)
但它看起来太冗长了.理想情况下,我希望有类似的东西:
myAuthorization {
.... my other routes here
}
Run Code Online (Sandbox Code Playgroud)
所以我这样写:
def myAuthorization: Directive0 =
formField("token".as[String]).require(isAuthorized(_))
Run Code Online (Sandbox Code Playgroud)
但是你会怎么写myAuthorization,以致它在请求中AuthorizationFailedRejection没有抛出token?
我正在使用
val akkaV = "2.2.3"
val sprayV = "1.2.0"
Seq(
"io.spray" % "spray-can" % sprayV,
"io.spray" % "spray-routing" % sprayV,
"io.spray" %% "spray-json" % "1.2.5",
"io.spray" % "spray-testkit" % sprayV,
"com.typesafe.akka" %% "akka-actor" % akkaV,
"com.typesafe.akka" %% "akka-testkit" % akkaV,
Run Code Online (Sandbox Code Playgroud)
并收到此错误:
找不到参数marshaller的隐含值:spray.httpx.marshalling.ToResponseMarshaller [List [org.bwi.models.Cluster]]
使用此代码:
object JsonImplicits extends DefaultJsonProtocol {
val impCluster = jsonFormat2(Cluster)
}
trait ToolsService extends HttpService with spray.httpx.SprayJsonSupport {
val myRoute = {
import JsonImplicits._
path("") { get { getFromResource("tools.html") } } ~
pathPrefix("css") { get { …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Scala和spray-client编写一个简单的HTTP客户端.我的客户基于Spray文档上给出的示例.
我的问题是该示例是创建一个新的隐式 ActorSystem即
implicit val system = ActorSystem()
Run Code Online (Sandbox Code Playgroud)
但我希望我的客户端可以重用,而不是创建一个新的ActorSystem.
这是我的代码的要点.
trait WebClient {
def get(url: String)(implicit system: ActorSystem): Future[String]
}
object SprayWebClient extends WebClient {
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
def get(url: String): Future[String] = {
val r = pipeline (Get("http://some.url/"))
r.map(_.entity.asString)
}
}
Run Code Online (Sandbox Code Playgroud)
但我得到两个关于implicits的编译器错误
implicit ActorRefFactory required: if outside of an Actor you need an implicit ActorSystem, inside of an actor this should be the implicit ActorContext WebClient.scala ...
Run Code Online (Sandbox Code Playgroud)
和
not enough arguments for …Run Code Online (Sandbox Code Playgroud) 我在我的喷雾罐服务器中使用以下路径(使用喷雾1.2):
path("my"/"path"){
get{
complete{
val buf:Array[Byte] = functionReturningArrayofByte()
println(buf.length)
buf
}
}
}
Run Code Online (Sandbox Code Playgroud)
缓冲区的长度(以及上面代码打印的内容)是2,263,503字节.但是,my/path从Web浏览器访问时,它会下载长度为10,528,063字节的文件.
我认为spray将内容类型设置为application/octet-stream,并在完成时自动设置内容长度Array[Byte].我没有意识到我可能做错了什么.
编辑
我运行了一个小测试,并看到字节数组输出为String.因此,例如,如果我有两个字节,例如0xFF和0x01,那么输出而不仅仅是两个字节将是字符串[ 255, 1 ].我只是不知道如何输出原始内容而不是它的字符串表示.
我正在进行基于令牌的身份验证,我不知道我应该如何authenticate在我的路由中使用指令:
我access_token从标题中得到了.
post {
headerValueByName("Access_Token") {
access_token => {
authenticate(??????){
user => {
......
......
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何进行身份验证?
我正在使用ask(?)来获取一个Set[String]来自Actor 的类型的值.但是,演员返回Future[Any].
什么是将此转换的正确方法Future[Any]来Future[Set[String]]?
val result : Future[Any] = myactor ? GetSomeValue
//convert Future[Any] to Future[Set[String]]
Run Code Online (Sandbox Code Playgroud) 我有一个API类,灵感来自我在这里写的喷雾scala演示,它将在喷涂路径中将Person渲染为JSON对象.
trait UsersApi {
case class Person(name: String, firstName: String, age: Int)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val PersonFormat = jsonFormat3(Person)
}
import MyJsonProtocol._
import spray.httpx.SprayJsonSupport._
import spray.util._
val bob = Person("Bob", "Parr", 32)
val usersApiRouting: Route = {
path("users") {
get {
complete {
marshal(bob)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是marshal(bob)返回JSON,如下所示:
{
"name": "Bob",
"firstName": "Parr",
"age": 32
}
Run Code Online (Sandbox Code Playgroud)
想象一下,我需要像这样渲染没有"年龄"的JSON:
{
"name": "Bob",
"firstName": "Parr"
}
Run Code Online (Sandbox Code Playgroud)
怎么能实现这一目标?我有一个想法是Scala有办法使一个对象成为另一个对象属性的子集吗?或者也许spray-json有一些特定的支持,不会编组一个不应该添加到服务器响应的属性?
喷雾文档有关于onComplete指令的示例
我复制了例子:
path("divide" / IntNumber / IntNumber) { (a, b) =>
onComplete(divide(a, b)) {
case Success(value: Any) => complete(s"The result was $value")
case Failure(ex) => complete(StatusCodes.InternalServerError, s"An error occurred: ${ex.getMessage}")
}
}
def divide(a: Int, b: Int): Future[Int] = Future {
a / b
}
Run Code Online (Sandbox Code Playgroud)
我得到了错误:
Type mismatch, expected: onCompleteFutureMagnet[NoninferedT], actual Future[Int]
Run Code Online (Sandbox Code Playgroud)
似乎在代码中遗漏了一些非常简单的东西.
喷涂版本为1.3.1
更新
我已经下载了喷雾源并在FutureDirectivesSpec中看到了相同的编译错误.
我正在尝试将case类转换为jsonspray.io json。下面的代码:
case class Value(amt: Int)
case class Item(name: String, count: Value)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val itemFormat = jsonFormat2(Item)
}
import MyJsonProtocol._
import spray.json._
val json = Item("mary", Value(2)).toJson
println(json)
Run Code Online (Sandbox Code Playgroud)
给出:
could not find implicit value for evidence parameter of type onextent.bluecase.examples.ex1.ExampleJson2.MyJsonProtocol.JF[Value]
Run Code Online (Sandbox Code Playgroud)
我也尝试JsonProtocol为Value 定义一个值,但得到相同的值。搜索stackoverflow我只看到与相关的错误generics,但不是。
我想念什么?(现在重新阅读有关隐式的信息...)
我有这条路线:
path("rus") {
complete("??????!")
}
Run Code Online (Sandbox Code Playgroud)
当我使用浏览器(chrome)进入/ rus时,得到以下输出:
“ !!”!
为什么?响应头是:
HTTP/1.1 200 OK
Server: akka-http/2.4.10
Date: Mon, 10 Oct 2016 22:31:53 GMT
Content-Type: application/json
Content-Length: 15
Run Code Online (Sandbox Code Playgroud)
我曾经使用过喷雾,但现在我想使用akka http,我没有遇到过这样的问题。
当我卷曲此路径时,我得到正常输出
$ curl http://localhost:9010/rus
"??????!"
Run Code Online (Sandbox Code Playgroud)
我看到响应标头'Content-Type'应该是'application / json; charset = utf-8'但缺少charset ...
spray ×10
scala ×7
akka ×3
spray-json ×2
access-token ×1
actor ×1
akka-http ×1
implicits ×1
json ×1
types ×1