我正在使用Spray + Akka(我想说“框架”,但他们希望被称为“图书馆”)。我收到一个REST电话,然后我回复了一个回复。但是,我发现我的处理有点重复。当我从两个API收到POST
请求时,这是两个块:
post {
entity(as[JObject]) { company =>
if (AuthInfo.rejectedOrNot) {
val response = (secCompanyActor ? jObjectFromWeb(company))
.mapTo[TransOk]
.map(result => result.succeedOrNot match {
case true => (OK, "transaction successful")
case false => (BadRequest, result.errorMessage)
}).recover { case _ => (BadRequest, "An error has occurred! We will fix this")}
complete(response)
} else {
complete(Unauthorized, "Please use HTTP header to authorize this command.")
}
}
另一个块非常相似,但唯一的区别是不是发送jObjectFromWeb(...)
,而是发送此消息:jObjectFromComputer(...)
。
我想创建一个函数,我传入消息然后从该函数发送消息,但Akka的消息不是TYPED!我理解来自无类型信息的哲学,我不是在争论什么,但我想要一个很好的解决方案。是的,一个解决方案是我传入一个像sendMessageToActor(actor, "jObjectFromWeb")
这样的字符串,在实际的函数中,我使用模式匹配来发送相应的消息。
但它有点难看而且不是很模块化(如果我要发送10条消息怎么办?)。
有没有办法做到这一点?我对Java的反射并不熟悉,但如果我能通过字符串找到消息案例类/对象,那将是非常好的。
这是我的Akka演员实施方:
class SECCompanyActor extends Actor with ActorLogging {
import com.mturk.tasks.SECcompany.SECCompanyProtocol._
def receive = {
case jObjectFromCasper(jObject) =>
//Do some logic
sender ! TransOk(result._1, result._2, result._3)
case jObjectFromWeb(jObject) =>
// Do some other logic
sender ! TransOk(result._1, result._2, result._3)
}
这是我的Akka消息:
object SECCompanyProtocol {
case class jObjectFromCasper(jObject: JObject)
case class TransOk(company: Option[Company.Company], succeedOrNot: Boolean, errorMessage: Option[String])
case class jObjectFromWeb(jObject: JObject)
}
答案 0 :(得分:1)
这个怎么样:
def doPost(messageConstructor: Company => AnyRef): Route = {
entity(as[JObject]) { company =>
if (AuthInfo.rejectedOrNot) {
val response = (secCompanyActor ? messageConstructor(company))
.mapTo[TransOk]
.map(result => result.succeedOrNot match {
case true => (OK, "transaction successful")
case false => (BadRequest, result.errorMessage)
}).recover { case _ => (BadRequest, "An error has occurred! We will fix this")}
complete(response)
} else {
complete(Unauthorized, "Please use HTTP header to authorize this command.")
}
}
}
post {
doPost(jObjectFromWeb.apply)
}
正如您的评论所述,当jObjectFromWeb
/ jObjectFromComputer
为案例类时,此方法有效。 jObjectFromWeb.apply
对应于案例类的apply
方法'伴随对象,它是为案例类自动创建的。更安全的类型设计将从单个特征继承两个案例类:
trait GenericJObject {
val company: Company
}
case class JObjectFromWeb(override val company: Company) extends GenericJObject
case class JObjectFromComputer(override val company: Company) extends GenericJObject
def doPost(messageConstructor: Company => GenericJObject): Route = {
...
}
此外,对于可维护性以及理解您的代码以遵守Scala编码约定更好,其中类名以大写字母开头,否则有人可能会感到困惑并认为jObjectFromXXX
是一种方法而不是案例类。