0

私は自分のサービスをこのように宣言しています:

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 クライアント ( to ws://localhost:9000/api/bloggie/tock ) を使用して呼び出すと、応答として「未定義」が返され、その URL のマッピングが見つからないことが示されました。

いくつかの実験の後、理由がわかりました: tick は、url パラメータ (:interval) を持っているため機能します。url パラメータがないため、Tick は機能しません。真剣に pathCall は、URL に param を含める必要がありますか? そこで、サービスの 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)

ありがとう!

4

1 に答える 1

1

したがって、まず、namedCallパスを気にしない場合にのみ使用する必要があります。サービス呼び出しを直接呼び出しています。つまり、パスを気にする必要があるため、pathCallまたはを使用する必要がありrestCallます。

これはうまくいくはずです:

pathCall("/api/bloggie/tock", this::tock)

また、完全なエラーを貼り付けていないと思います。Guiceエラーのリストの一番下まで確認してください。問題が何であるかを正確に説明しているはずです。上記の多くの場合、問題はメソッド参照を渡していないことです。ラムダを渡しています。 、そしてエラーメッセージはそれを言うべきです。

于 2016-05-16T00:40:03.557 に答える