java - 将 List 转换为 akka.japi.Function[akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage[akka.http.javadsl.model.HttpResponse]]*
问题描述
我正在尝试动态添加传递给函数的服务concatOrNotFound
import akka.grpc.javadsl.ServiceHandler;
import akka.http.javadsl.model.HttpRequest;
import akka.http.javadsl.model.HttpResponse;
import akka.japi.function.Function;
Function<HttpRequest, CompletionStage<HttpResponse>> greeterService =
GreeterServiceHandlerFactory.create(new GreeterServiceImpl(mat), sys);
Function<HttpRequest, CompletionStage<HttpResponse>> echoService =
EchoServiceHandlerFactory.create(new EchoServiceImpl(), sys);
@SuppressWarnings("unchecked")
Function<HttpRequest, CompletionStage<HttpResponse>> serviceHandlers =
ServiceHandler.concatOrNotFound(greeterService, echoService);
Http.get(sys)
.newServerAt("127.0.0.1", 8090)
.bind(serviceHandlers)
(https://doc.akka.io/docs/akka-grpc/current/server/walkthrough.html)
具有以下concatOrNotFound
方法签名:
@scala.annotation.varargs
def concatOrNotFound(handlers : akka.japi.Function[akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage[akka.http.javadsl.model.HttpResponse]]*) : akka.japi.Function[akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage[akka.http.javadsl.model.HttpResponse]] = { /* compiled code */ }
如何将greeterService
&echoService
作为 List 传递,然后ServiceHandler.concatOrNotFound
在此调用List
?
作为handlers
可变参数,我尝试了以下方法:
List serviceList = new ArrayList();
serviceList.add(eventService);
serviceList.add(echoService);
@SuppressWarnings("unchecked") // Calling varargs method with generic instances
final Function<HttpRequest, CompletionStage<HttpResponse>> serviceHandlers =
ServiceHandler.concatOrNotFound(l.toArray(new Function[serviceList.size()]));
但这因编译器错误而失败:
Cannot resolve method 'concatOrNotFound(java.lang.Object[])'
我试图实现的是使用转换为可变参数的服务列表传递给 concatOrNotFound 方法。我想使用列表的原因是列表将根据条件逻辑填充,该逻辑将确定哪些服务被添加到列表中。
我正在考虑的另一个选项是遍历列表并为每个列表元素调用 concatOrNotFound ,其中每个列表元素都是一个服务。
更新:
这似乎可以List
使用可变参数传递 into 方法:
List<akka.japi.Function<akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage<akka.http.javadsl.model.HttpResponse>>> serviceList = new ArrayList();
serviceList.add(eventService);
serviceList.add(echoService);
final Function<HttpRequest, CompletionStage<HttpResponse>> serviceHandlers =
ServiceHandler.concatOrNotFound(Iterables.toArray(serviceList, akka.japi.Function.class));
显式键入 List 类型参数以
List<akka.japi.Function<akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage<akka.http.javadsl.model.HttpResponse>>>
由于类型擦除而需要?
解决方案
我假设在这种情况下,scala 来源的编译字节码可能与实际预期的编写源代码不同。这是 Scala 编程的缺陷之一,对于 vararg Scala/Java 互操作性尤其如此。
要么,要么greeterService
和echoService
被推断为没有公共层次结构的不同类型,可能是由于可变参数转换本身。这就是在您的第一次尝试中将它们推断为Object
类型的原因。查看ServiceHandler的源代码: JFunction 是预期的
对于您的第二次尝试,您List serviceList = new ArrayList();
再次执行此操作,将元素推断为Object
实例,因此编译器失败。
将 List 类型参数显式键入到 List<akka.japi.Function<akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage<akka.http.javadsl.model.HttpResponse>>>
由于类型擦除而需要?
是的,它是必需的,但它与类型擦除无关。泛型类型作为编译过程的一部分被丢弃。提供具体元素类型仅允许编译器理解正确的类型被传递给期望它们的函数调用
我面前没有源代码,但您最初可以键入将您的服务转换为JFunction
实例。您可能会有更好的运气。另一种方法是使用正确类型的JFunction
数组来收集它们。
推荐阅读
- c++ - 使用 Qt 连接时的 Visual Studio 警告
- git - 两个 git commit 有相同的 `abbrev-commit` 的机会是什么
- swift - 无法在列表视图上使用解析的数据
- javascript - 显示查询的 jqgrid 选项
- linux - 如何将我电脑上的当前 node.js 开发设置部署到物理 ubuntu 服务器?
- javascript - FullCalendar 添加资源默认事件值
- drools - Drools 说订单和产品类型不匹配
- amazon-web-services - 如何根据大小将大 s3 文件拆分为多个文件?
- tensorflow - 需要帮助了解 tf.contrib.layers.fully_connected 训练权重
- javascript - 在画布中设置背景图像(织物js)