在 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]
需要一些隐式,但它们很容易进入作用域。
有没有办法将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]
需要一些隐式,但它们很容易进入作用域。