在 Akka-Http 中将路由转换为流 Java

Convert Route to Flow in Akka-Http for Java

有没有办法将javadsl Route转为Flow?在 Scala 中,我们有 handlerFlow 隐式可用,但在 Java 中我们没有类似物。

尝试调用 handlerFlow,但它使用 scaladsl 类型并且与 Route 的 javadsl 版本不兼容。

我想使用 API 的低级版本来绑定到 http 和 https,并能够访问连接。

============================
更新: 我使用了 svezfaz 的答案中的想法,现在我得到了代码:

Flow<HttpRequest, HttpResponse, NotUsed> createFlow(ActorSystem system, Materializer mat) {
  scala.Function1<akka.http.scaladsl.server.RequestContext, scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>> r = RouteImplementation.apply(createRoute());
  Flow f = RouteResult$.MODULE$.route2HandlerFlow(
      r,
      RoutingSettings$.MODULE$.apply(system),
      ParserSettings$.MODULE$.apply(system),
      mat,
      RoutingLog$.MODULE$.fromActorSystem(system),
      null,
      RejectionHandler$.MODULE$._mthdefault(),
      null
      ).asJava();
  return f;
}

它看起来是正确的,但它无法编译。可能,我必须将 Scala 库包含到类路径中。然后使用其他 Scala 到 Java 类型的转换。

我认为重写 w/o Java 中的路由更容易。

您可以从 akka.http.javadsl.server.HttpServiceBase 中汲取灵感(见下文)。 使用RouteImplementation将javadsl转换为scaladsl,然后调用route2HandlerFlow转换为flow。

  /**
   * Uses the route to handle incoming connections and requests for the ServerBinding.
   */
  def handleConnectionsWithRoute(interface: String, port: Int, route: Route, system: ActorSystem, materializer: Materializer): CompletionStage[ServerBinding] = {
    implicit val s = system
    implicit val m = materializer

    import system.dispatcher
    val r: server.Route = RouteImplementation(route)
    Http(system).bind(interface, port).toMat(Sink.foreach(_.handleWith(akka.http.scaladsl.server.RouteResult.route2HandlerFlow(r))))(Keep.left).run()(materializer).toJava
  }

在akka-http 10.0.6中,可以使用

akka.http.scaladsl.server.Route.handlerFlow(route: Route): Flow[HttpRequest, HttpResponse, NotUsed]

需要一些隐式,但它们很容易进入作用域。