3

質問はばかげている/些細なことのように思えるかもしれませんが、自分の目標を達成する方法を理解できません。(タイトルが間違っていたらごめんなさい、もっといいものを思いつきませんでした)

GWT を使用する App Engine サーバー上に Web ページがあります。クライアントコードとサーバーコードを取得しました。クライアント コードは問題なく RPC メソッドを呼び出すことができます (私の問題は"gwt-client" とはまったく関係ありません)

次のクラスを取得しました。

//MyClassService.java - client package
@RemoteServiceRelativePath("myService")
public interface MyClassService extends RemoteService{
   public doSomething();
}

//MyClassServiceAsync.java - client package
public interface MyClassServiceAsync{
   public void doSomething(AsyncCallback<Void> callback);
}

//MyClassServiceImpl.java - server package
public class MyClassServiceImpl extends RemoteServiceServlet implements MyClassService{
   @Override
   public void doSomething()
   {
      //does something
   }
}

シナリオとやりたいこと: リモート クライアント、つまり、「GWT インターフェース」を介してページを介して接続していないクライアントを持っています。これは、単に GET を作成しているクライアントであり、パスへの POST 要求です。サーバー上(他の場所から)。このリモート クライアントは、GWT をまったく「使用」していません。クライアントは HttpServlet を介して接続しています。このサーブレット内で RPC メカニズムを再利用したいので、クライアント側にあり、クライアント依存のコードを使用しているインターフェイスを書き直す必要はありません (実装は既にサーバー側です)。 )。

サーバー側で既存のメソッドを再利用するには、MyClassServiceImpl.java のインスタンスを作成し、それらをそのまま使用します。しかし、上記のように、GWT-RPC を使用すると GWT-RPC は自動的に呼び出しを非同期にするため、これらは同期メソッドとして実装されます。

サーバー側で MyClassServiceImpl を再利用し、それらを非同期として取得するにはどうすればよいですか?

また、私が取っているアプローチが間違っている場合は、他の解決策を提案してください。たとえば、1 つの解決策は、クライアントが接続する HttpServlet を作成する代わりに、リモート クライアントが RemoteServiceServlet と直接通信することかもしれませんが、それが可能かどうかはわかりません (可能な場合は方法を教えてください)。

ありがとうございました!

編集(以下のいくつかの回答のおかげで、洞察を得て、質問を改善しようとします):

メソッドのサーバー側の実装は SYNCHRONOUS です。つまり、結果が返されるまでブロックされます。これらのメソッドを gwt-client コードから呼び出すと、「自動的に」非同期になり、次のようにして呼び出すことができます。

MyClassServiceAsync = (MyClassServiceAsync) GWT.create(MyClassService.class);
ServiceDefTarget serviceDef = (ServiceDefTarget) service;
serviceDef.setServiceEntryPoint(GWT.getModuleBaseURL() + "myService");

service.doSomething(new AsyncCallback<Void>() {
 @Override
 public void onSuccess(Void result) {
   //do something when we know server has finished doing stuff
 }

 @Override
 public void onFailure(Throwable caught) {
 }
});

上記のコードからわかるように、doSomething メソッドが AsyncCallback を取得するためのサポートがあり、そのための実装はありません。これは私がサーバー側で望んでいたことなので、スレッドを使用したり、「非同期使用」のための新しい実装を作成したりする必要はありませんでした。わかりにくかったらすいません!

4

2 に答える 2

1

1) どのクライアントもMyClassServiceImpl.doSomething()現在の構成で呼び出すことができます。MyClassServiceImplサーブレットであり、適切に公開されています。この方法で通信を行うには、クライアントはデータ転送用の GWT 方言を「話す」ことができなければなりません。Google は、これを実装するライブラリを提供する場合があります。私は何も使用していないので、提案することはできません。

概念実証セットアップの例: Firebug とのネットワーク通信をチェックして、何が起こっているかを把握します。次に、でサービスを呼び出してみてくださいcurl

2) GWT ダイアレクトを使用したくない場合は、同じサービスを REST (JSON) または Web サービス (SOAP) として簡単に公開できます。REST ケースのRestEasyJerseyなど、たくさんのライブラリがあります。サーバー側のフレームワーク (Spring? Guice? CDI?) について言及していないため、例は単純化されています。

輸送方法とは独立したクラスでビジネス方法を実装することをお勧めします。

public class MyBusinessLogic {
    public void doSomething() {
        ...
    }
}

次に、トランスポート実装はこのビジネス ロジック クラスを使用し、トランスポート固有のもの (注釈など) のみを追加します。

GWT:

public class MyClassServiceImpl extends RemoteServiceServlet implements MyClassService{
    @Override
    public void doSomething() {
        MyBusinessLogic bean = ... // get it from IoC, new, whatever
        bean.doSomething();
    }
}

JAX-RS:

@Path("myService")
public class MyResource {
    @GET
    public void doSomething() {
        MyBusinessLogic bean = ... // get it from IoC, new, whatever
        bean.doSomething();
    }
}

したがって、トランスポート エンドポイントは、クラスという 1 つの場所に実装された、実際の機能の単なるシェルですMyBusinessLogic

于 2013-11-06T12:48:58.803 に答える