RESTful POSTメソッドでパラメーターにアクセスする方法


123

私のPOSTメソッドは次のようになります。

@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String param1, String param2){
    System.out.println("param1 = " + param1);
    System.out.println("param2 = " + param2);
}

NetbeansでJersey Clientを作成すると、postメソッドを呼び出すメソッドは次のようになります。

public void create(Object requestEntity){
    webResource.path("create").type(MediaType.APPLICATION_JSON).post(requestEntity);
}

このテストを実行するとき:

@Test
public void hello(){
    String json = "{param1=\"hello\",param2=\"hello2\"}";
    this.client.create(json);
}

サーバーで次の出力が得られます。

INFO: param1 = {param1="hello",param2="hello2"}
INFO: param2 = 

パラメータが正しい値を与えるために何を変更する必要がありますか?


あなたはこれをAndroidアプリケーションで使用していますか?
Android-Droid

最後に、Androidアプリでこのpostメソッドを呼び出します。どういうわけか、Webサービスはパラメーターに値を署名する方法を知りません。これを行う方法を知りたいです。
Klaasvaak

回答:


355

あなたの@POST方法ではなく、文字列のJSONオブジェクトを受け入れるべきです。JerseyはJAXBを使用して、JSONオブジェクトのマーシャリングとアンマーシャリングをサポートします(詳細については、ジャージーのドキュメントを参照してください)。次のようなクラスを作成します。

@XmlRootElement
public class MyJaxBean {
    @XmlElement public String param1;
    @XmlElement public String param2;
}

その場合、@POSTメソッドは次のようになります。

@POST @Consumes("application/json")
@Path("/create")
public void create(final MyJaxBean input) {
    System.out.println("param1 = " + input.param1);
    System.out.println("param2 = " + input.param2);
}

このメソッドは、HTTP POSTの本体としてJSONオブジェクトを受け取ることを想定しています。JAX-RSは、HTTPメッセージのコンテンツ本文を注釈なしパラメーターとして渡しますinput(この場合)。実際のメッセージは次のようになります。

POST /create HTTP/1.1
Content-Type: application/json
Content-Length: 35
Host: www.example.com

{"param1":"hello","param2":"world"}

この方法でJSONを使用することは、明らかな理由から非常に一般的です。ただし、JavaScript以外で生成または使用する場合は、データを適切にエスケープするように注意する必要があります。JAX-RSでは、MessageBodyReaderおよびMessageBodyWriterを使用してこれを実装します。Jerseyには、JSONだけでなく、必要な型(JavaプリミティブやJAXBラップされたクラスなど)の実装がすでにあると思います。JAX-RSは、データを渡すための他の多くのメソッドをサポートしています。データは単純な引数渡しを使用して渡されるため、これらは新しいクラスの作成を必要としません。


HTML <FORM>

パラメータには@FormParamを使用して注釈を付けます。

@POST
@Path("/create")
public void create(@FormParam("param1") String param1,
                   @FormParam("param2") String param2) {
    ...
}

ブラウザは"application / x-www-form-urlencoded"を使用してフォームをエンコードします。JAX-RSランタイムが本体をデコードし、それをメソッドに渡します。ワイヤーで見るべきものは次のとおりです。

POST /create HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 25

param1=hello&param2=world

この場合、コンテンツはURLエンコードされています

FormParamの名前がわからない場合は、次の操作を実行できます。

@POST @Consumes("application/x-www-form-urlencoded")
@Path("/create")
public void create(final MultivaluedMap<String, String> formParams) {
    ...
}

HTTPヘッダー

HTTPヘッダーを介してパラメーターを渡す場合は、@ HeaderParamアノテーションを使用できます。

@POST
@Path("/create")
public void create(@HeaderParam("param1") String param1,
                   @HeaderParam("param2") String param2) {
    ...
}

HTTPメッセージは次のようになります。このPOSTには本体がないことに注意してください。

POST /create HTTP/1.1
Content-Length: 0
Host: www.example.com
param1: hello
param2: world

このメソッドは、一般化されたパラメーターの受け渡しには使用しません。ただし、特定のHTTPヘッダーの値にアクセスする必要がある場合に非常に便利です。


HTTPクエリパラメータ

このメソッドは主にHTTP GETで使用されますが、POSTにも同様に適用できます。@QueryParamアノテーションを使用します。

@POST
@Path("/create")
public void create(@QueryParam("param1") String param1,
                   @QueryParam("param2") String param2) {
    ...
}

前のテクニックと同様に、クエリ文字列を介してパラメーターを渡す場合、メッセージ本文は必要ありません。これがHTTPメッセージです。

POST /create?param1=hello&param2=world HTTP/1.1
Content-Length: 0
Host: www.example.com

クライアント側でクエリパラメータを適切にエンコードするには、特に注意する必要があります。クエリパラメータの使用は、一部のプロキシによって適用されるURLの長さの制限と、それらのエンコーディングに関連する問題により、問題になる可能性があります。


HTTPパスパラメータ

パスパラメータは、HTTPリソースパスに埋め込まれていることを除いて、クエリパラメータに似ています。この方法は今日好まれているようです。パスは実際にHTTPリソースを定義するものであるため、HTTPキャッシングに関して影響があります。@Pathアノテーションが変更されており、@ PathParamを使用しているため、コードは他のコードと少し異なります

@POST
@Path("/create/{param1}/{param2}")
public void create(@PathParam("param1") String param1,
                   @PathParam("param2") String param2) {
    ...
}

メッセージはクエリパラメータバージョンに似ていますが、パラメータの名前がメッセージのどこにも含まれていない点が異なります。

POST /create/hello/world HTTP/1.1
Content-Length: 0
Host: www.example.com

このメソッドは、クエリパラメータバージョンと同じエンコーディングの問題を共有します。 パスセグメントは異なる方法でエンコードされるので、そこでも注意する必要があります。


ご覧のとおり、それぞれの方法には長所と短所があります。選択は通常、クライアントによって決定されます。FORMベースのHTMLページを提供している場合は、を使用します@FormParam。クライアントがJavaScript + HTML5ベースの場合、おそらくJAXBベースのシリアライゼーションとJSONオブジェクトを使用する必要があります。MessageBodyReader/Writer間違って行くことができる1つの少なく事になるように、実装はあなたのために必要なエスケープの世話をする必要があります。クライアントがJavaベースであるが、優れたXMLプロセッサ(Androidなど)がない場合はFORM、コンテンツボディの生成とエンコードがURLよりも簡単なので、おそらくエンコードを使用します。うまくいけば、このミニwikiエントリは、JAX-RSがサポートするさまざまなメソッドにいくつかの光を当てることができます。

注:完全に開示するために、私は実際にはジャージーのこの機能をまだ使用していません。多数のJAXB + JAX-RSアプリケーションがデプロイされており、モバイルクライアントスペースに移動しているため、私たちはそれをいじくり回していました。JSONは、HTML5またはjQueryベースのソリューションのXMLよりもはるかに適しています。


4
私は昨日この機能をテストしましたが、@ XmlElementアノテーションは必要あり
ません

これをありがとう。それでも2つの文字列を送信したい場合、restfullは何を消費できる必要がありますか?または、複数のパラメーターは@PathParmでのみ機能しますか?
Klaasvaak

1
@Klaasvaak-各パラメーターの抽出元となる場所を指定する必要があります。これで、Jersey / NetBeansはフォームポストを想定し、FormParmとして送信されたデータを抽出しています。各メソッド拡張に注釈を付ける場所(PathParam、FormParam、CookieParamなど)のデータの場所
Perception

1
@Klaasvaak-さまざまな注釈を使用して
多数

2
本当にありがとうございました!これは本当に私が探していたものでした。あなたは私の日を作りました;)私は今FormParamsを使用していて、それは機能します!
Klaasvaak 2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.