有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

scala将列表转换为akka。贾皮。函数[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进入as列表,然后在这个List上调用ServiceHandler.concatOrNotFound

由于handlers是一个varargs,我尝试了以下方法:

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[])'

我试图实现的是使用一个服务列表,该列表被转换为varargs,并被传递到concatOrNotFound方法中。我想使用列表的原因是,列表将根据条件逻辑填充,条件逻辑将决定哪些服务被添加到列表中

我正在考虑的另一个选项是迭代列表,并为每个列表元素调用concatOrNotFound,其中每个列表元素都是服务

更新:

这似乎可以使用varargs参数将List传递给方法:

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<akka.japi.Function<akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage<akka.http.javadsl.model.HttpResponse>>>

由于类型擦除而需要吗


共 (1) 个答案

  1. # 1 楼答案

    我假设在这种情况下,源于scala的编译字节码可能与实际的预期编写源代码不同。这是scala编程的陷阱之一,尤其是在Varag scala/Java互操作性方面

    或者greeterServiceechoService被推断为没有公共层次结构的不同类型,可能是由于vararg转换本身。这就是在你第一次尝试时,它们被推断为Object类型的原因。看看ServiceHandler的源代码:应该是JFunction

    对于第二次尝试,您正在执行List serviceList = new ArrayList(); 这同样会将元素推断为Object实例,因此编译器会失败

    Is explicitly typing the List type parameters to List<akka.japi.Function<akka.http.javadsl.model.HttpRequest, java.util.concurrent.CompletionStage<akka.http.javadsl.model.HttpResponse>>>

    required as a result of type erasure ?

    是的,这是必需的,但与类型擦除无关。泛型类型作为编译过程的一部分被丢弃。提供具体的元素类型只允许编译器理解正确的类型被传递给期望它们的函数调用

    我面前没有源代码,但您可以首先键入convert将服务转换为JFunction实例。你的运气可能会更好。另一种方法是首先使用正确键入的JFunction数组来收集它们