5

次のような一連の JAX-RS ロケーターとサブロケーターがあるとします。

@Path("/users")
public class UserListResource {
   @Path("/{id}")
   public UserResource getCustomer(@PathParam("id") int id) {
      // Find and return user object
   }
}

public class UserResource {
  @GET
  public String get() {...}
}

たとえばUserResource、 ID5を持つオブジェクトのパスは になります"/users/5"。私のシステムには、いくつかの異なるリソースがあります。

問題は、サーバーが特定のリソースのパスをどのように把握できるかということです。JAX-RS API を介してプログラムでこれを行うことはできますか? それとも、リフレクションを使用するコードを実装する必要がありますか? (後者の方法は知っていますが、他のアプローチを好むでしょう。)

  • パスを知る必要がある時点で、リクエスト オブジェクトがまったくありません。たとえば、いくつかのバックグラウンド処理を行うタイマーがあり、ドメイン モデル内のいくつかのエンティティを変更し、変更されたエンティティ (パスを含む) についてすべてのクライアントに通知します。
  • リクエストのスコープ内で、UriInfoこれを提供するオブジェクトを注入できることはわかっていますが、事前にパスを知る必要があります (必ずしも JAX-RS リソースを介して発生したとは限らない変更をクライアントに通知するため)。
  • パス情報を別の場所で繰り返したくありません。また、各リソース タイプ (この場合は"/users""/{id}") の一連のパス フラグメント定数も必要ありません。
4

4 に答える 4

3

あなたの質問を読むと、リソース クラスとidパラメーターだけを知っている URI を作成する必要があります。

UriBuilder 次のようにクラスを使用して実行できます。

UriBuilder builder=UriBuilder.fromResource(UserListResource.class);
URI uri=builder.path(UserListResource.class,"getCustomer").build(5);

内部でリフレクションを使用しているため、リファクタリングは簡単ではありませんが、現時点で利用できるのはこれだけです。

于 2013-02-04T10:22:42.630 に答える
1

全体として、アプリケーションのアーキテクチャに関しては、何かが奇妙に聞こえることに注意してください。指を置くのは難しいですが、あなたが尋ねている質問のパターンは、あなたがこれについてどのように行っているかについて多くの危険信号を上げています. アプリケーションに RESTful API を作成しようとしている場合は、停止する必要がある場合があることに注意してください。数歩戻って、何をしようとしているのかを再考してください。

あなたの明白な質問に…</p>

問題は、サーバーが特定のリソースのパスをどのように把握できるかということです。JAX-RS API を介してプログラムでこれを行うことはできますか? それとも、リフレクションを使用するコードを実装する必要がありますか? (後者の方法は知っていますが、他のアプローチを好むでしょう。)

パスは常にユーザーによって提供され、アプリケーションを構成するリソース クラスのコレクションをナビゲートするために使用されるため、サーバーはパスを認識します。特定の呼び出しのインスタンスが必要なUriInfo場合は、その特定の呼び出しの一部としてそれを挿入する必要があります。

@GET
public String get(@Context UriInfo info) {...}

外部コンテキストから必要な情報 (リソースの ID など) は、構築中に渡すのが最適です。URL (から取得可能) から再解析することもできますがUriInfo、それはおそらく間違ったアプローチです。

それ以外の場合は、もっと複雑なことをしている場合は、質問をより具体的にする必要があります。

  • パスを知る必要がある時点で、リクエスト オブジェクトがまったくありません。たとえば、いくつかのバックグラウンド処理を行うタイマーがあり、ドメイン モデル内のいくつかのエンティティを変更し、変更されたエンティティ (パスを含む) についてすべてのクライアントに通知します。
  • リクエストのスコープ内で、UriInfoこれを提供するオブジェクトを注入できることはわかっていますが、事前にパスを知る必要があります (必ずしも JAX-RS リソースを介して発生したとは限らない変更をクライアントに通知するため)。

どのようにクライアントに通知しますか?通常、サーバーからクライアントにメッセージをプッシュするメカニズムはなく、クライアントは通常、サービスを直接ホストできないようにファイアウォールで保護されています。

理論的には、クライアントが選択した場合にリッスンできる独自の RSS フィードに各リソースを (明示的に、URL によって) 関連付けることができます。クライアントに聞くように強制することはできませんが、そうするオプションを与えることはできます。このルートを使用する場合UriInfo、位置情報は重要な時間 (つまり、リソースの作成時) に存在し、その後は自分が制御できる何かを参照するだけなので、「事前」を知る必要はありません。 .

しかし、これは 1 つの方法にすぎず、複雑さが増します。アプリケーションにとって重要な場合にのみ実行します。多くの場合、クライアントに時々ポーリングさせる方が簡単です。(特に ID の変更やリソースの削除など、ある種の変更は本質的に非常に破壊的であることに注意してください。物事がそれらにスムーズに対処できるとは期待しないでください。)

  • パス情報を別の場所で繰り返したくありません。また、各リソース タイプ (この場合は " /users" と " /{id}") ごとに一連のパス フラグメント定数を保持する必要もありません。

タフ。単一の情報源から一貫して情報を引き出す場合、複数の場所で情報を繰り返すことは一般的な方法です。実際には何も問題はありません。

于 2013-02-04T11:25:33.010 に答える
0

あなたの質問を理解しているので、リクエストが入ってきたときのパスを知りたいのですが、それがリソースに到達する前に; サーブレット フィルターの使用にオープンですか?

JAX-RS 固有のフィルターは 2.0 でのみサポートされています

于 2013-01-31T10:29:38.643 に答える
0

記録として: 質問を投稿した後、アーキテクチャについてもう少し考えてみたところ、URL の送信は思ったほど役に立たないという結論に達しました。いずれにせよ、アプリケーションはアプリケーションの構造に関するいくつかの詳細を知る必要があります。

  • 上記の例を続けると、クライアントが個々のユーザーの URL パターンを知らなくても、ユーザーのリストが存在し、その URL を知っていると想定する必要があります。また、ユーザーなどを編集するために表示するダイアログをハードコーディングした知識もあります。

つまり、クライアントが必要とする (ほとんどの) URL をクライアントに伝えようとしても、努力する価値はありません。代わりに、リソースのコンテンツとその URL スキームに関するデータを含むカスタム API 定義ファイルを使用することにしました。このファイルは、次のものを生成するために使用されます。

  • 正しい JAX-RS アノテーションを持つサーバー側のリソース クラス
  • 他の開発者がコーディングするための URL スキーム仕様書
  • 独自のクライアント用のクラス (URL のノウハウを含む。たとえば、ID 5 のユーザーは URL を持っている...) であるため、クライアントとサーバー間の不一致について心配する必要はありません。

このアプローチには、次の利点があります。

  • オブジェクト ID を含む通知を受信すると、クライアントが独自にそれを行うことができるようになるため、サーバーが注釈から URL を把握する必要がなくなります。
  • すべての情報は単一のソースから取得されるため、クライアントとサーバー間の不一致について心配する必要はありません。
  • 古いリリースとの下位互換性を検証するために使用できる、バージョン管理下の API 定義のソースが 1 つあります。

注: 結果として得られる API が RESTful Web サービスの考え方に「忠実」であるとはおそらく主張しませんが、それは私たちにとって機能し、「実際の」REST アーキテクチャ スタイルから借用した要素により、API はより明確で習得が容易になるはずです。従来のコントラクト優先の Web サービス。

于 2013-02-05T09:36:05.543 に答える