标签: spray

喷涂中的布线设计

我正在尝试为个人资料管理提供休息服务.所以我有以下uri的配置文件:

host/profile/id123123/:action
Run Code Online (Sandbox Code Playgroud)

但是对于具有不同仪表板的不同用户,存在不同的配置文件类型,因此我想提取profileTypeid作为顶部路径并在此下使用不同的操作.我试着用DRY方式写它:

path(Segment / "id" ~ Segment) { (profileType, id) ?
  get {
    profileType match {
      case "admin" ? loadProfilePage[Admin](id)
    }
  } ~
  path("update") {
    complete("Profile updated")
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在地址栏中键入以下内容:

localhost/admin/id123123/update
Run Code Online (Sandbox Code Playgroud)

它抛出服务器异常.有什么问题?

rest routing scala spray

1
推荐指数
1
解决办法
1723
查看次数

无法将消息返回给Spray HttpService Actor

我正在学习Spray和Akka.使用其中一个路由存根构建了一个简单的Spray路由应用程序 -

path("blog" / LongNumber) {
  blogId =>
    respondWithMediaType(MediaTypes.`application/json`) {
      get {
        request => BlogFetchActor ! Get(blogId)
      }
    }
 }
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我在我的喷涂路由定义(在实现HttpService的类中)中将消息分派给请求中具有ID(blogId)的另一个Actor.BlogFetchActor应该从数据库中获取数据并响应发送者.我的编码如下 -

def receive: Receive = LoggingReceive {
  case Get(id: Long) => {
    log.debug("Retrieving blog with id %d".format(id))
      sender ! ReturnBlog(get(id))
  }
 }
Run Code Online (Sandbox Code Playgroud)

来自路线的Actor消息正在进入我的BlogFetchActor.我的BlogFetchActor也完成了从数据库中获取数据的工作.但是当我尝试将响应发送回发件人HttpService,ReturnBlog消息时,它不起作用.消息最终在DeadLetters中,我在我的日志中看到以下内容 -

从演员[akka:// on-spray-can/user/blog-service/blog#1301907662]到演员[akka:// on-spray-can/deadLetters]的消息[in.bharathwrites.BlogFetchActor $ ReturnBlog]不是交付.

为什么回复给发件人的回复不起作用?我究竟做错了什么?我怎么能做到这一点?我试过阅读Spray文档和ScalaDoc,但无法弄清楚问题.我不够精通阅读Spray代码并了解原因......提前致谢

scala akka spray

1
推荐指数
1
解决办法
412
查看次数

如何读取Spray Can的端口配置?

我正在尝试设置一个基本的Spray Can服务器.在代码中,我看到了这个:

IO(Http) ! Http.Bind(service, interface = "localhost", port = 8080)
Run Code Online (Sandbox Code Playgroud)

我想从application.conf文件配置该端口(8080).但是,conf文件的格式(http://spray.io/documentation/1.2-M8/spray-can/configuration/)没有定义端口.

这是否意味着实现此目的的方法是自己定义端口配置,并从application.conf中读取它?如果是这样,这是怎么做到的?

port scala spray

1
推荐指数
1
解决办法
1764
查看次数

来自喷雾路线的催生演员感到困惑

我正在使用Spray进行一些Http请求处理.对于一个请求,我启动一个actor并将有效负载发送给actor以进行处理,并且在演员完成有效负载之后,我呼吁context.stop(self)演员将演员缠绕下来.这个想法是为了防止演员身上的过度饱和.机.

这就是我设置的方式..

httphandler.scala,我的路线设置如下:

path("users"){
   get{
      requestContext => {
         val userWorker = actorRefFactory.actorOf(Props(new UserWorker(userservice,requestContext)))
        userWorker ! getusers //get user is a case object 
      }
   }
} ~ path("users"){
     post{
       entity(as[UserInfo]){
          requestContext => {
          userInfo => {
             val userWorker = actorRefFactory.actorOf(Props(new UserWorker(userservice,requestContext)))
             userWorker ! userInfo
           }
         }
       }
     }
 }
Run Code Online (Sandbox Code Playgroud)

我的UserWorker演员定义如下:

trait RouteServiceActor extends Actor{
  implicit val system = context.system
  import system.dispatcher
  def processRequest[responseModel:ToResponseMarshaller](requestContex:RequestContext)(processFunc: => responseModel):Unit = {
       Future{
         processFunc
       } onComplete {
          case Success(result) => …
Run Code Online (Sandbox Code Playgroud)

asynchronous scala actor akka spray

1
推荐指数
1
解决办法
2220
查看次数

喷涂路线问题和未来[选项[String]]

我想采用一个返回a的函数,并将其Future[Option[String]]与spray routing的onComplete指令结合使用.但无论我做什么,我似乎无法让它发挥作用.

假设我有以下功能:

def expensiveOperation: Future[Option[String]] = { ... do stuff ... }
Run Code Online (Sandbox Code Playgroud)

然后我想定义我的一部分Route:

onComplete(expensiveOperation) {
  case Success(string) => complete(string)
  case Failure(_) => complete("failure")
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在不编写单独的函数的情况下将其Future[Option[String]]转换为基本函数Future[String]

scala spray

1
推荐指数
1
解决办法
848
查看次数

没有找到喷雾清单Marshaller

此代码导致编译错误could not find implicit value for parameter marshaller: spray.httpx.marshalling.ToResponseMarshaller[List[akka.actor.ActorRef]].

我不认为问题是ActorRef,因为改变它.mapTo[List[String]]显示相同的编译错误

一般来说,喷雾如何编组与所有暗示有点混淆 - 有没有办法使这个明确,例如ListProtocol.marshal(value)

import akka.actor.Actor
import spray.http.HttpResponse
import spray.http.HttpRequest
import spray.http.Uri
import spray.http._
import spray.routing._
import HttpMethods._
import akka.actor.ActorRef
import akka.pattern.ask
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Success
import scala.util.Failure
import spray.http.StatusCodes.InternalServerError
import spray.json.DefaultJsonProtocol
import spray.httpx.SprayJsonSupport._
import spray.httpx.marshalling._
import spray.http._

class HttpApi(val manager: ActorRef) extends HttpServiceActor {

  def receive = runRoute {
    path("nodes") {
      get {
        onComplete(manager.ask(NodeList())(3.seconds).mapTo[List[ActorRef]]) {
          case Success(value) => {
            // …
Run Code Online (Sandbox Code Playgroud)

scala akka spray spray-json spray-dsl

1
推荐指数
1
解决办法
966
查看次数

RequestContext.reject如何工作?

看看喷雾API,它RequestContext是不可变的并RequestContext.reject返回Unit- 那么Spray路由如何知道"请求"被拒绝了?

http://spray.io/documentation/1.2.2/spray-routing/key-concepts/routes/

即:我们说我们有路线:a-> b

如果b拒绝请求(通过调用RequestContext.reject)如何a通知它?

我想我不确定"响应者"(参见文档中的响应者链)的文档意味着什么RequestContext.响应者b会是a吗?或者响应者是Actor发起http请求的原始人吗?

scala akka spray

1
推荐指数
1
解决办法
844
查看次数

如何解析json与喷json使用蛇案(下划线表示法)而不是骆驼案

如何解析json与喷json使用蛇案(下划线表示法)而不是骆驼案?

例如

case class Test(subjectDescription: String)
"{\"subject_description\":\"Medicine\"}".parseJson.convertTo[Test]
Run Code Online (Sandbox Code Playgroud)

应该工作,而不是抛出异常.

json scala spray spray-json

1
推荐指数
1
解决办法
1660
查看次数

如何通过使用 sbt-docker 或手动编写 docker 文件在 docker 中运行 sbt 项目?

我一直在努力学习在 docker 中运行一个 sbt 项目。我也想用喷雾。我正在遵循 sbt-docker 在 github 中提供的示例: https://github.com/marcuslonnberg/sbt-docker/tree/master/examples/package-spray 当我拉项目时,它工作正常,我可以运行docker 容器也是如此。

project > project > PackageSprayBuild.scala 中有一个文件我不知道这个文件是如何使用的。此外,给定的示例没有 plugins.sbt 文件。

然后我尝试创建我的单独项目。

我的plugins.sbt看起来像这样:

logLevel := Level.Warn

addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "1.2.0")
Run Code Online (Sandbox Code Playgroud)

我的build.sbt看起来与我上面提到的示例几乎相同。

name := "demo-docker-sbt"

version := "1.0"

scalaVersion := "2.11.7"

resolvers += "spray repo" at "http://repo.spray.io/"

libraryDependencies ++= Seq(
  "io.spray" % "spray-can" % "1.2.0",
  "io.spray" % "spray-routing" % "1.2.0",
  "com.typesafe.akka" %% "akka-actor" % "2.2.3")

enablePlugins(DockerPlugin)

// Make docker depend on the package task, which generates a …
Run Code Online (Sandbox Code Playgroud)

scala sbt playframework spray docker

1
推荐指数
1
解决办法
7883
查看次数

找不到 Akka-HTTP 路由?

我正在学习使用构建服务器Akka-Http,这是我到目前为止所写的

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.stream.{Materializer, ActorMaterializer}
import spray.json.DefaultJsonProtocol
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._

import scala.concurrent.ExecutionContextExecutor


// todo() : add event timestamp
case class ECFailure(symbolicName:String)


trait Protocols extends DefaultJsonProtocol {
  implicit val ecFailureFormat = jsonFormat1(ECFailure.apply)
}

trait EmailService extends Protocols {
  implicit val system: ActorSystem
  implicit def executor: ExecutionContextExecutor
  implicit val materializer: Materializer

  val route =
    logRequestResult("email-service") {
      pathPrefix("ec") {
        (post & entity(as[ECFailure])) { ecFailure =>
          complete {
            println("received: " + ecFailure)
            "Done"
          }
        }
      }
      path("") { …
Run Code Online (Sandbox Code Playgroud)

scala akka spray akka-http

0
推荐指数
1
解决办法
3174
查看次数

将一种类型的可选项简单映射到另一种类型(如果存在)?

所以我有一堆采用这种格式的案例类:

case class A(value: String)
case class B(value: String)
case class C(value: String)
Run Code Online (Sandbox Code Playgroud)

我在函数中接受了几个Option [String]值作为参数,如果参数中的值不是None,我想创建Option [A],Option [B].

我现在这样做:

val first = parameterOptional match {
    case Some(theStringValue) => Some(A))
    case None => None
}
Run Code Online (Sandbox Code Playgroud)

它有效,但我想知道是否有更简洁的方法来做到这一点,我对Scala很新.

示例中的变量名称显然已被更改.

谢谢

scala pattern-matching for-comprehension spray

0
推荐指数
1
解决办法
81
查看次数

Scala类型不匹配同一父节点的子类

UserGetResponse和GeneralResponse是BaseResponse的子类,如下所示:

abstract class BaseResponse()
Run Code Online (Sandbox Code Playgroud)

我用来检索用户的函数如下:

  def userGet(userId: Int)(implicit ec: ExecutionContext): Future[BaseResponse] = Future {
    val response = users.get(userId) map { user =>
        val userRes = new UserResponse(user.id, user.firstname, user.lastname, user.organisationid, user.email, user.password, user.usertype)
        new UserGetResponse(1, "Successful retrieved the user.", userRes)
    } getOrElse {
      GeneralResponse(0, s"Error retrieving user. User does not exist.")
    }
  }
Run Code Online (Sandbox Code Playgroud)

其中users是另一个定义了get,insert等方法的类.我收到以下编译错误:

 type mismatch;
[error]  found   : Unit
[error]  required: package.name.BaseResponse
[error]   }
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

scala spray apache-spark

0
推荐指数
1
解决办法
121
查看次数

Spray JSON无法序列化案例类

我正在尝试使用Spray将以下案例类与JSON相互转换:

case class Interval(lower: Int, upper: Int)
Run Code Online (Sandbox Code Playgroud)

这可以通过以下方式实现:

implicit val intervalFormat = jsonFormat2(Interval)
Run Code Online (Sandbox Code Playgroud)

这样可以编译,但是会给出运行时错误:

无法自动确定案例类字段名称和“间隔”的顺序,请使用“ jsonFormat”重载并使用明确的字段名称规范

搜索此错误表明,通常在子类声明其他字段时会出现此错误,此处不是这种情况。

我是否误以为Spray应该能够自动格式化间隔类?

如果是这样,那么(如错误消息所示)我是否应该为格式化程序提供有关Interval字段的更明确的信息?如何最容易实现?

编辑:@retrospectacus的答案提供了一些有用的观点,但是它们都不能解决问题。我采用的解决方法是对字段的类型和名称进行明确描述:

implicit val intervalFormat = jsonFormat[Int, Int,Interval](Interval, "lower", "upper")
Run Code Online (Sandbox Code Playgroud)

这行得通,但我仍然悬而未决,因为尚不清楚为什么有必要这样做。

json scala spray

0
推荐指数
1
解决办法
226
查看次数