最新版Akka-Http自定义RejectionHandler不生效问题排查求助
akka-http 10.2.x 自定义RejectionHandler不生效问题解决方案
问题原因
- akka-http 从10.2.0版本开始调整了RejectionHandler的默认应用逻辑:隐式声明的自定义RejectionHandler不会自动被未密封的路由拾取,而10.1.x版本中会自动应用作用域内的隐式handler,这是跨版本行为不一致的核心原因。
- 你代码中定义的自定义Handler仅处理了单个
MethodRejection实例,但实际路由方法不匹配时,akka-http会生成一组MethodRejection集合,默认内置handler会优先处理这类批量rejection,也会导致自定义逻辑无法触发。
修复方案
推荐使用显式绑定Handler的方式,兼容所有akka-http版本,修改后可运行的代码如下:
import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.{MethodRejection, RejectionHandler, Route} import akka.http.scaladsl.server.Directives._ object MyApp extends App { val myRejectionHandler = RejectionHandler.newBuilder() // 用handleAll批量处理所有MethodRejection集合 .handleAll[MethodRejection] { _ => complete((StatusCodes.NotFound, "Not here!")) }.result() implicit val system = ActorSystem() val rawRoute: Route = path("index") { post { complete(StatusCodes.OK) } } // 显式给外层路由绑定自定义RejectionHandler,不依赖隐式优先级规则 val route = handleRejections(myRejectionHandler)(rawRoute) Http().newServerAt("localhost", 8080).bind(route) }
如果需要保留隐式声明的写法,也可以通过显式密封路由的方式实现:
implicit val myRejectionHandler = RejectionHandler.newBuilder() .handleAll[MethodRejection] { _ => complete((StatusCodes.NotFound, "Not here!")) }.result() implicit val system = ActorSystem() val rawRoute: Route = path("index") { post { complete(StatusCodes.OK) } } // 显式调用seal方法,自动拾取作用域内的隐式RejectionHandler val route = Route.seal(rawRoute) Http().newServerAt("localhost", 8080).bind(route)
内容的提问来源于stack exchange,提问作者Johny T Koshy
相关产品推荐
相关产品推荐

