web-dev-qa-db-ja.com

ジャージーPOSTメソッドはパラメーターとしてnull値を受信して​​います

私はJerseyでRESTfulサービスを開発しており、GETメソッドでうまく機能します。しかし、私はそれをPOSTメソッドとJSONまたはテキストパラメータで動作させることができません。これらは私がやったことです:

@Path("/method/")
@POST
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@Produces({MediaType.APPLICATION_JSON})
public ResponseObject method(@Context Request request, @PathParam("ob1") Object obj1, @PathParam("obj2") String obj2) {
...
}

すべてのパラメーターでnull値しか取得できません。私は文字列だけをパラメータとして使用しようとしましたが、それも機能しません... IOSからこれらのメソッドにアクセスしようとしていますが、おそらくそれが問題の1つです。しかし、 LANをスニッフィングすると、パケット本体に正しいパラメーターが表示されます...これは正しいですか?

XCodeから別の本文コンテンツを送信しました:

obj1={"id1": "value1", "id2" : "value2"}&obj2=xxxx

そして:

{"id1": "value1", "id2" : "value2"},xxxx

@QueryParamと@PathParamで遊んでいても、結果は得られません...常にnull ...

ご協力いただきありがとうございます!

13
Kasas

パスパラメータは、特定のパターンに一致するリクエストURLの一部です。そのため、パスパラメータとして指定できる文字には制限があります。特に、特殊文字はURLエンコードする必要があります。これは、あらゆる種類のリクエストに同じように適用されます([〜#〜] get [〜#〜][〜#〜] post [〜#〜]、- [〜#〜] put [〜#〜][〜#〜] delete [〜#〜])。

一般的なルールとして、パスパラメータを識別子やリソースエンドポイントなどの単純な値に制限する必要があります。より複雑なデータは、リクエストパラメータまたはリクエスト本文自体を介してRESTサービスに渡す必要があります。ここにあります。エンティティ識別子をパスパラメータとして渡し、リクエストボディでエンティティデータを渡す混合アプローチ:

_@Path("/contacts/{id}")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateContact(@PathParam final String contactId, Contact contact) {
}
_

上記の例では、contactIdがパスパラメータとして取得され、連絡先はリクエストの本文から自動的にシリアル化されます。

上記で説明したのは一般ルールです。今あなたのケースの詳細に関して、私があなたのコードで気づく1つのことは、あなたが実際にどんなパスパラメータも定義していないということです。 RESTメソッドで使用する前に、_@Path_アノテーションの一部として定義する必要があります。

_@Path("/method/{obj1}/{obj2}")
public ResponseObject method(@Context Request request, @PathParam("obj1") Object obj1, @PathParam("obj2") String obj2) {
}
_

上記の変更により、クライアント側でURLが適切にエンコードされていれば、パラメーターはnullとして表示されなくなります。


*編集*

あなたのコメントに基づいて、JAX-RS仕様とさまざまなパラメーターの型について、もっと理解する必要があると思います。 RESTEasy JAX-RS Documentation を一読することをお勧めします。ベンダー固有の実装の詳細がいくつかありますが、全体としてはJAX-RSの優れたガイドです。


@PathParam

Purpose:リクエストURLの一部を変数に挿入するために使用されます。 URLパラメータはnotと見なされ、URLの一部と見なされます。

:指定されたURL http://services.example.com/contacts/ 20578、次のように定義できます:

_@Path("/contacts/{id}")
_

そこから@PathParam("id")を注入できます。

_public Response getContact(@PathParam("id") final String identifier);
_

これはany種類のHTTPリクエスト([〜#〜] get [〜#〜][〜#〜] post [〜#〜]で機能します[〜#〜] put [〜#〜][〜#〜] delete [〜#〜])。


@QueryParam

Purpose:クエリ文字列の一部を注入するか、エンコードされたデータを変数にフォームするために使用されます。クエリ文字列は、URLの_?_の後の部分です。フォームエンコードされたデータは、リクエストタイプがapplication/x-www-form-urlencodedの場合に、HTTPリクエストの本文で渡されるURLエンコードされた名前と値のペアのデータです。通常、クエリパラメータは、GETリクエストの場合はURL文字列の一部として、POSTリクエストの場合はリクエスト本文で渡されます。

例:URL http://services.example.com/contacts?group=Business を指定すると、@QueryParam("group")を挿入できます

_public Response getContactsInGroup(@QueryParam("group") final String groupName);
_

POSTリクエストでクエリパラメータを使用することは一般的ではありませんが、リクエストタイプがapplication/x-www-form-urlencodedの場合は可能です:

_@POST
@Path("/contacts")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createContact(@QueryParam("contact") final Contact contactData, @QueryParam("metadata") final String metaData);
_

これらは高レベルの例にすぎません。リンクされた documentation を読んで、各パラメータータイプがどのように機能するか、どのタイプをいつ使用するかについてのより良い例を入手してください。

25
Perception

JavaでWebサービスの開発を始めたばかりで、POSTデータで同じ問題が発生しました。 @ FormParam を使用してPOSTデータを読み取るための非常に簡単な解決策を得ました、実際には @ QueryParam POSTデータを読み取るために、GETメソッドを使用してQueryStringデータを読み取るための唯一の方法だと思います

ここに与えられた非常に素晴らしいドキュメント。この記事を読んだことで、私の混乱のほとんどは解消されました。 http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html

ヒント:@FormParamを使用する際は、「application/x-www-form-urlencoded」MIMEタイプを使用していることを確認してください

6
iNeal

受け入れられた回答へのコメントとしてこれを投稿しますが、私はそれができるのが恥ずかしいです。

上記の優れたアドバイスに加えて、少なくともバージョン2.0.xでは、ジャージーはクエリ文字列から@FormParamをプルしません。代わりに、リクエストの本文に名前と値のペアとして含まれることを想定しています。

たとえば、POST http://localhost/app?name=Joeの代わりに、本文とともにPOST http://localhost/appを送信します。

name=Joe
1
Jennifer Wood