喷Akka Json解组

Bil*_*ALP 5 scala akka spray spray-json spray-routing

我有一个关于通过使用Spray-Akka将对象解组到Json的问题。

当我想使用返回Future [List [Person]]的actor时,它将无法正常工作。

如果我直接使用dao对象,则可以使用。

这是我的代码:

人道斯卡拉

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

case class Person(id: Int, name: String, surname: String)

object PersonDao {

  def getAll: Future[List[Person]] = Future {
    List[Person](Person(1, "Bilal", "Alp"), Person(2, "Ahmet", "Alp"))
  }
}
Run Code Online (Sandbox Code Playgroud)

EntityServiceActor.scala

import akka.actor.Actor
import com.bilalalp.akkakafka.model.PersonDao
import com.bilalalp.akkakafka.service.ServiceOperation.FIND_ALL

object ServiceOperation {

  case object FIND_ALL

}

class EntityServiceActor extends Actor {

  override def receive: Receive = {

    case FIND_ALL => PersonDao.getAll
  }
}
Run Code Online (Sandbox Code Playgroud)

ServerSupervisor.scala

import akka.actor.{Actor, ActorRefFactory}
import com.bilalalp.akkakafka.webservice.TaskWebService
import spray.routing.RejectionHandler.Default


class ServerSupervisor extends Actor with PersonWebService {

  implicit val system = context.system

  override def receive: Receive = runRoute(entityServiceRoutes)

  override implicit def actorRefFactory: ActorRefFactory = context
}
Run Code Online (Sandbox Code Playgroud)

WebServiceTrait.scala

import akka.util.Timeout

import spray.routing.HttpService

import scala.concurrent.duration._
import scala.language.postfixOps

import org.json4s.NoTypeHints
import org.json4s.native.Serialization._

trait WebServiceTrait extends HttpService {

  implicit def executionContext = actorRefFactory.dispatcher

  implicit val json4sFormats = formats(NoTypeHints)

  implicit val timeout = Timeout(120 seconds)
}
Run Code Online (Sandbox Code Playgroud)

PersonWebService.scala

trait PersonWebService extends WebServiceTrait with Json4sSupport {

  val json3sFormats = DefaultFormats

  val entityServiceWorker = actorRefFactory.actorOf(Props[EntityServiceActor], "entityServiceActor")

  val entityServiceRoutes = {
    pathPrefix("person") {
      pathEndOrSingleSlash {
        get {
          ctx => ctx.complete((entityServiceWorker ? FIND_ALL).mapTo[Person])
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Application.scala

import akka.actor.{ActorRef, ActorSystem, Props}
import akka.io.IO
import com.bilalalp.akkakafka.server.ServerSupervisor
import spray.can.Http


object Application extends App {

  implicit val system = ActorSystem("actorSystem")

  val mainHandler: ActorRef = system.actorOf(Props[ServerSupervisor])
  IO(Http)! Http.Bind(mainHandler, interface = Configuration.appInterface, port = Configuration.appPort)

}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,它什么也没有给出,并等待一段时间。

等待之后,浏览器给出以下消息:

服务器无法及时响应您的请求。

控制台输出为

[错误] [11/22/2015 21:15:24.109] [actorSystem-akka.actor.default-dispatcher-7] [akka.actor.ActorSystemImpl(actorSystem)]处理请求HttpRequest(GET,http:/ / localhost:3001 / person /,列表(主机:localhost:3001,连接:保持活动状态,Cache-C控制:无缓存,实用程序:无缓存,用户代理:Mozilla / 5.0(Windows NT 6.3; WOW64)AppleWebKit / 537.36(KHTML,如Gecko)Maxthon /4.4.6.1000 Chrome / 30.0.1599.101 Safari / 537.36,DNT:1,Accept-Encoding:gzip,deflate,Accept-Language:tr-TR),Empty,HTTP / 1.1)akka.pattern.AskTimeoutException:询问超时[120000毫秒]之后[Actor [akka:// actorSystem / user / $ a / entityServiceActor#-1810673919]]。Sender [null]发送了类型为“ com.bilalalp.akkakafka.service.ServiceOperation $ FIND_ALL $”的消息。at akka.pattern.PromiseActorRef $$ anonfun $ 1.apply $ mcV $ sp(AskSupport.scala:415)at akka.actor.Scheduler $$ anon $ 7.run(Scheduler.scala:132)at scala.concurrent.Future $ InternalCallbackExecutor在scala.concurrent上的$ .unbatchedExecute(Future.scala:599)。

如果我将PersonWebService.scala更改为此:

trait PersonWebService extends WebServiceTrait with Json4sSupport {

  val json3sFormats = DefaultFormats

  val entityServiceWorker = actorRefFactory.actorOf(Props[EntityServiceActor], "entityServiceActor")

  val entityServiceRoutes = {
    pathPrefix("person") {
      pathEndOrSingleSlash {
        get (
//                    ctx => ctx.complete((entityServiceWorker ? FIND_ALL).mapTo[Person])
          ctx => ctx.complete(PersonDao getAll)
        )
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它的工作原理是:

[{{id“:1,” name“:” Bilal“,” surname“:” Alp“},{” id“:2,” name“:” Ahmet“,” surname“:” Alp“}]

我想在喷雾路线中使用演员。我不知道这是不是一个坏习惯,因为我是akka和spray的新手。

我该如何解决?有任何想法吗?

谢谢。

Tim*_*lim 3

您需要将结果发送回发送者:

case FIND_ALL =>
  PersonDao.getAll.pipeTo(sender())
Run Code Online (Sandbox Code Playgroud)