2

同じコードを使用して、クライアント側とサーバー側でオブジェクトをソートおよび操作したいと考えています。

しかし、クライアントではサーバーのクラスを表すプロキシ インターフェイスが必要なため、問題に直面しています。

両方で同じインターフェイスを使用する方法はありますか? RF には、Bean 属性がネットワーク経由で送信されるときに、サーバー インスタンスからクライアント インスタンスに Bean 属性をコピーするメカニズムがあることがわかっています。

4

3 に答える 3

1

同じ API を使用する 1 つの方法は、プロキシが拡張し、ドメイン オブジェクトが実装するインターフェイスを使用することです。

// common interfaces
interface Foo { … }
interface Bar<T extends Foo> {
  int getX();
  void setX(int x);

  // setters need to use generics
  List<T> getFoos();
  void setFoos(List<T> foos);

  // with only a getter, things get easier:
  Bar getParent();
}

// domain objects
class RealFoo implements Foo { … }
class RealBar implements Bar<RealFoo> {
  int x;
  List<RealFoo> foos;
  RealBar parent;

  @Override
  public RealBar getParent() { return parent; }

  // other getters and setters
}

// proxy interfaces
@ProxyFor(RealFoo.class)
interface FooProxy extends Foo { … }

@ProxyFor(RealBar.class)
interface BarProxy extends Bar<FooProxy> {
  @Override
  BarProxy getParent();

  // other getters and setters
}

その後、クライアント側とサーバー側の両方でComparator<Foo>orを使用できます。Comparator<Bar>

私は一般的に、完全なドメイン オブジェクトの API ではなく、特性(アスペクトファセット、好きなように呼び出す) のみをそのように実装します ( HasIdHasLabel、など)。HasPosition次にHasId、任意のオブジェクトのキーを取得して、それらをマップに配置したり、同等性を比較したり、表示したりできHasLabelます (クライアント側のカスタムCells、クライアントに送信されるサーバー側のエラー メッセージなど)。 、HasPosition仕分け用など

于 2013-04-06T15:54:05.403 に答える
0

RequestFactory のポイントは、同じ型を使用しないことです。各リクエスト コンテキストは、呼び出しがサーバーに到達したときに実行する一連の操作を記述します (作成および検索、セッターの適用、サービス メソッドの実行)。呼び出しはサーバー上の本物への単なるプロキシとして記述されるため、実行できる呼び出しがゲッターとセッターのみであることを保証するために、 EntityProxyorのような「偽の」モデル オブジェクトが必要です。ValueProxyオブジェクトがサーバーから読み取られたが、編集される前の場合)。

モデルが単純な場合、つまり、他のオブジェクトを保持せず、文字列、日付、およびプリミティブのみを保持する場合、エンティティとプロキシの両方に同じインターフェイスを実装させることができます。ただし、モデルがサブオブジェクトを保持している場合、これはより困難です。可能な唯一の方法は、それらのゲッターとセッターを除外することです。そうしないと、プロキシ タイプでこれらのメソッドをオーバーライドして、ネストされたオブジェクトのプロキシ バージョンを指定することはできません。

クライアントとサーバーで同じ型を実際に再利用したい場合は、RPC の代わりに使用することを検討してください。

于 2013-04-06T15:23:58.470 に答える
0

トーマスが答えで言っているように、現在の GWT でクライアントとサーバーでコードを共有する唯一の方法は、両側で同じインターフェースを実装し、それを共有コードで使用することです。

クエリで言うように、RF はサーバーからクライアントに属性をコピーするため、理論的には、@ValueFor 値をそれ自体を指すように設定して、両側で同じインターフェイス (プロキシ インターフェイス) を使用できます (より単純なコード)。

例を見てみましょう:

 // Shared interface in client and server sides
 @ProxyFor(Foo.class)
 interface Foo extends ValueProxy {
    String getBar();
 }

 // Server side implementation
 class FooImpl implements Foo {
    String getBar(){return "bar";};
 }

情報として、2 つのバックエンド ソリューション (1 つは GAE ベース、もう 1 つは couchdb ベース) を販売できるように、製品でこのアプローチを使用しています。

上記のコードは、新しい値を作成しないクライアント コードに対して機能しますが、それらを作成する場合は、値ロケーターを定義するだけで十分です。

 // Say RF which locator to use to create classes in server side
 @ProxyFor(value = Foo.class, locator ALocator.class)
 interface Foo extends ValueProxy {
 }

 public class ALocator extends Locator<Foo, String>  {
   public Foo create(Class<? extends Foo> clazz) {
    return new FooImpl();
   }
   ...
 }

残念ながら、RF はサーバー側のインターフェースを処理しません: 問題 7509および5762を参照してください。

しかし、問題のコメントを読むことができるように、これに対する修正は既にあります(レビュー待ち)。GWT の次のリリースに含まれることを願っています。

それまでの間、このアプローチを使用して、ファイルResolverServiceLayer.javaを src フォルダーにコピーし、このパッチを適用するだけです。

于 2013-04-06T22:40:57.680 に答える