私の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 =
パラメータが正しい値を与えるように変更する必要がありますか。
あなたの@POST
メソッドは文字列の代わりにJSONオブジェクトを受け取るべきです。 JerseyはJSONオブジェクトの整列化と非整列化をサポートするためにJAXBを使用します(詳細については jerseyのドキュメントを参照 を参照)。以下のようなクラスを作成してください。
@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¶m2=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¶m2=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 + HTML 5ベースの場合は、おそらくJAXBベースのシリアル化とJSONオブジェクトを使用したいでしょう。 MessageBodyReader/Writer
の実装はあなたに必要なエスケープの面倒を見なければなりません。あなたのクライアントがJavaベースであるが、良いXMLプロセッサ(例えば、Android)を持っていないなら、私はおそらくコンテンツボディがURLより適切に生成してエンコードするのが簡単であるのでFORM
エンコーディングを使うでしょう。このmini-wikiエントリがJAX-RSでサポートされているさまざまな方法に光を当てることを願っています。
注:完全な開示のために、私は実際にはまだJerseyのこの機能を使用していません。 JAXB + JAX-RSアプリケーションが多数配備され、モバイルクライアントの分野に移行しているので、私たちはそれに慣れていました。 JSONは、HTML 5上のXMLまたはjQueryベースのソリューションよりもはるかに適しています。