MyService.scala:33: could not find implicit value for parameter eh: spray.routing.ExceptionHandler
我在使用Akka时遇到了"缺少隐式"的编译错误,在spray.io代码中,对一个单独的后端服务器进行http调用,作为响应http get的一部分.代码需要导入相当多的Spray和Akka库,因此有点难以确定是否存在导致此问题的库冲突,我宁愿想出如何在这个和其他情况下逻辑地跟踪这类问题.
在调用时遇到缺少的隐式 runRoute(myRoute)
这是代码:
import spray.routing._
import akka.actor.Actor
import akka.actor.ActorSystem
import spray.http._
import MediaTypes._
import akka.io.IO
import spray.httpx.RequestBuilding._
import scala.concurrent.Future
import spray.can.Http
import spray.http._
import akka.util.Timeout
import HttpMethods._
import akka.pattern.ask
import akka.event.Logging
import scala.concurrent.duration._
// we don't implement our route structure directly in the service actor because
// we want to be able to test it independently, without having to spin up an actor
class MyServiceActor extends Actor with MyService with akka.actor.ActorLogging {
log.info("Starting")
// the HttpService trait defines only one abstract member, which
// connects the services environment to the enclosing actor or test
def actorRefFactory = context
// this actor only runs our route, but you could add
// other things here, like request stream processing
// or timeout handling
def receive = runRoute(myRoute)
}
// this trait defines our service behavior independently from the service actor
trait MyService extends HttpService {
implicit val system: ActorSystem = ActorSystem()
implicit val timeout: Timeout = Timeout(15.seconds)
import system.dispatcher // implicit execution context
//val logger = context.actorSelection("/user/logger")
val logger = actorRefFactory.actorSelection("../logger")
val myRoute =
{
def forward(): String = {
logger ! Log("forwarding to backend")
val response: Future[HttpResponse] =
(IO(Http) ? Get("http:3080//localhost/backend")).mapTo[HttpResponse]
"<html><body><h1>api response after backend processing</h1></body></html>"
}
path("") {
get {
respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here
complete(forward)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道解决这个问题的最佳方法是什么,希望能够提供如何解决类似问题的洞察力,因为它们在某种程度上不能直接追踪.
编辑:当试图直接传递implicits,如下面的@ christian的答案,我得到:
MyService.scala:35: ambiguous implicit values:
both value context in trait Actor of type => akka.actor.ActorContext
and value system in trait MyService of type => akka.actor.ActorSystem
match expected type akka.actor.ActorRefFactory
RoutingSettings.default, LoggingContext.fromActorRefFactory)
^
不太确定为什么具体如@ christian的答案为编译器留下了歧义的空间......
cfc*_*hou 20
我今天早些时候遇到了"无法找到参数eh:spray.routing.ExceptionHandler的隐含值"错误.我尝试了@Christian的方法,但看到一些"xxx的隐含价值"逐渐上升.在侦察错误消息后,我发现添加implicit val system = context.system到runRoute解决问题的演员.
runRoute 需要一些隐含的内容。您缺少导入:
import spray.routing.RejectionHandler.Default
Run Code Online (Sandbox Code Playgroud)
更新: 我认为我们在 runRoute 方面也遇到了一些问题,因为我们显式提供了隐式参数:
runRoute(route)(ExceptionHandler.default, RejectionHandler.Default, context,
RoutingSettings.default, LoggingContext.fromActorRefFactory)
Run Code Online (Sandbox Code Playgroud)
Update2: 要修复最后一个错误,请删除 ActorSystem 的创建(在 MyService 中,您从 MyServiceActor 获取 actor 系统 - 因此您必须使用 self 类型注释)。这编译:
import akka.actor.Actor
import akka.io.IO
import spray.httpx.RequestBuilding._
import spray.http.MediaTypes._
import spray.routing.{RoutingSettings, RejectionHandler, ExceptionHandler, HttpService}
import spray.util.LoggingContext
import scala.concurrent.Future
import spray.can.Http
import spray.http._
import akka.util.Timeout
import HttpMethods._
import akka.pattern.ask
import akka.event.Logging
import scala.concurrent.duration._
// we don't implement our route structure directly in the service actor because
// we want to be able to test it independently, without having to spin up an actor
class MyServiceActor extends Actor with MyService with akka.actor.ActorLogging {
log.info("Starting")
// the HttpService trait defines only one abstract member, which
// connects the services environment to the enclosing actor or test
implicit def actorRefFactory = context
// this actor only runs our route, but you could add
// other things here, like request stream processing
// or timeout handling
def receive = runRoute(myRoute)(ExceptionHandler.default, RejectionHandler.Default, context,
RoutingSettings.default, LoggingContext.fromActorRefFactory)
}
// this trait defines our service behavior independently from the service actor
trait MyService extends HttpService { this: MyServiceActor =>
implicit val timeout: Timeout = Timeout(15.seconds)
implicit val system = context.system
//val logger = context.actorSelection("/user/logger")
val logger = actorRefFactory.actorSelection("../logger")
val myRoute =
{
def forward(): String = {
//logger ! Log("forwarding to backend")
val response: Future[HttpResponse] =
(IO(Http) ? Get("http:3080//localhost/backend")).mapTo[HttpResponse]
"<html><body><h1>api response after backend processing</h1></body></html>"
}
path("") {
get {
respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here
complete(forward)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6037 次 |
| 最近记录: |