我的服务是这样声明的:
public interface BlogQueryService extends Service {
public ServiceCall<String, Source<String, ?>> tick(int interval);
public ServiceCall<String, Source<String, ?>> tock();
public ServiceCall<NotUsed, Source<PostSummary, ?>> newPosts();
public ServiceCall<String, Source<PostSummary, ?>> getPostSummaries();
@Override
default Descriptor descriptor() {
return named("blog-query").with(
//pathCall("/api/bloggie/tick/:interval", this::tick),
pathCall("/api/bloggie/tock", tock())
//pathCall("/api/bloggie/newPosts", this::newPosts),
//pathCall("/api/bloggie/postSummaries", this::getPostSummaries)
).withAutoAcl(true);
}
}
滴答声有效。滴答声没有。
当我使用 websocket 客户端(到 ws://localhost:9000/api/bloggie/tock )调用它时,我得到“未定义”作为响应,表明没有找到该 URL 的映射。
经过一些实验,发现了原因:tick 有效,因为它具有 url 参数(:interval)。Tick 不起作用,因为它没有 url 参数。严重 pathCall 要求您在 URL 中有参数?所以我检查了服务的API:http ://www.lagomframework.com/documentation/1.0.x/api/java/com/lightbend/lagom/javadsl/api/Service.html
pathCall 有几个重载的声明。显然蜱虫使用这个:
static <Request,Response,A> Descriptor.Call<Request,Response> pathCall(String pathPattern, akka.japi.function.Function<A,ServiceCall<Request,Response>> methodRef)
所以从签名来看,是的,它需要方法来获取参数。因此,如果方法(例如 tock)不带参数,则绑定将在运行时失败。所以我想我需要改用这个:
static <Request,Response> Descriptor.Call<Request,Response> pathCall(String pathPattern, akka.japi.function.Creator<ServiceCall<Request,Response>> methodRef)
问题是......我不知道怎么做。我还没有看到在 pathCall 中使用 akka.japi.function.Creator 的任何示例。
我试过这个:
default Descriptor descriptor() {
return named("blog-query").with(
pathCall("/api/bloggie/tick/:interval", this::tick),
pathCall("/api/bloggie/tock", new Creator<ServiceCall<String, Source<String, ?>>> () {
public ServiceCall<String, Source<String, ?>> create() {
return tock();
}
})
//pathCall("/api/bloggie/newPosts", this::newPosts),
//pathCall("/api/bloggie/postSummaries", this::getPostSummaries)
).withAutoAcl(true);
}
它编译。但它在运行时抛出一个错误:
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error in custom provider, java.lang.IllegalStateException: Unable to resolve method for service call with ID PathCallId{pathPattern='/api/bloggie/tock'}. Ensure that the you have passed a method reference (ie, this::someMethod). Passing anything else, for example lambdas, anonymous classes or actual implementation classes, is forbidden in declaring a service descriptor.
at com.lightbend.lagom.javadsl.server.ServiceGuiceSupport.bindServices(ServiceGuiceSupport.java:43) (via modules: com.google.inject.util.Modules$OverrideModule -> sample.bloggie.impl.BlogServiceModule)
while locating com.lightbend.lagom.internal.server.ResolvedServices
提前致谢!
我只是做了一些实验......全部编译,但没有一个工作......
namedCall("/api/bloggie/tock", this::tock)
结果:编译成功。运行时:路径未知(无绑定 (?))。
然后我尝试了
pathCall("/api/bloggie/tock", () -> this.tock())
结果:异常。
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error in custom provider, scala.MatchError: Request (of class sun.reflect.generics.reflectiveObjects.TypeVariableImpl)
at com.lightbend.lagom.javadsl.server.ServiceGuiceSupport.bindServices(ServiceGuiceSupport.java:43) (via modules: com.google.inject.util.Modules$OverrideModule -> sample.bloggie.impl.BlogServiceModule)
while locating com.lightbend.lagom.internal.server.ResolvedServices
for parameter 1 at com.lightbend.lagom.internal.server.ServiceRegistrationModule$RegisterWithServiceRegistry.<init>(ServiceRegistrationModule.scala:55)
at com.lightbend.lagom.internal.server.ServiceRegistrationModule.bindings(ServiceRegistrationModule.scala:29):
Binding(class com.lightbend.lagom.internal.server.ServiceRegistrationModule$RegisterWithServiceRegistry to self eagerly) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
while locating com.lightbend.lagom.internal.server.ServiceRegistrationModule$RegisterWithServiceRegistry
然后我尝试了:
public ServiceCall<NotUsed, Source<String, ?>> tock(Void x);
结果:异常
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error in custom provider, java.lang.IllegalArgumentException: Don't know how to serialize ID class java.lang.Void
at com.lightbend.lagom.javadsl.server.ServiceGuiceSupport.bindServices(ServiceGuiceSupport.java:43) (via modules: com.google.inject.util.Modules$OverrideModule -> sample.bloggie.impl.BlogServiceModule)
更新:“已解决”(部分)。发现这个有效:
pathCall("/tock", this::tock)
我可以使用以下 URL 打开它:ws://localhost:9000/tock
所以......,当这些函数不需要参数时,我不能为那些返回流的函数提供结构良好的 URL?至少现在 (?)。
更新:似乎这个问题不仅发生在 pathCall 上。我在休息电话中遇到了同样的问题。这个不起作用(没有约束力):
public ServiceCall<NotUsed, PSequence<PostSummary>> getPostSummaries();
...
restCall(Method.GET, "/api/bloggie/postSummaries", this::getPostSummaries)
这个有效:
public ServiceCall<NotUsed, PSequence<PostSummary>> getPostSummaries();
...
restCall(Method.GET, "/postSummaries", this::getPostSummaries)
谢谢!