私はこのメソッドでRESTfull Webサービスを使用しています:
@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String str1, String str2){
System.out.println("value 1 = " + str1);
System.out.println("value 2 = " + str2);
}
Androidアプリで、このメソッドを呼び出します。 org.Apache.http.client.methods.HttpPostを使用してパラメーターに正しい値を与える方法
アノテーション@HeaderParamを使用して、ヘッダーをHttpPostオブジェクトに追加するだけでよいことに気付きました。これは正しい方法ですか?次のようにします:
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("str1", "a value");
httpPost.setHeader("str2", "another value");
HttpPostでsetEntityメソッドを使用しても機能しません。パラメータstr1にjson文字列のみを設定します。次のように使用する場合:
JSONObject json = new JSONObject();
json.put("str1", "a value");
json.put("str2", "another value");
HttpEntity e = new StringEntity(json.toString());
httpPost.setEntity(e);
//server output: value 1 = {"str1":"a value","str2":"another value"}
パラメータをHttpPostRequest
に設定するには、次のようなBasicNameValuePair
を使用できます。
HttpClient httpclient;
HttpPost httppost;
ArrayList<NameValuePair> postParameters;
httpclient = new DefaultHttpClient();
httppost = new HttpPost("your login link");
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("param1", "param1_value"));
postParameters.add(new BasicNameValuePair("param2", "param2_value"));
httpPost.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));
HttpResponse response = httpclient.execute(httpPost);
いくつかのhttpパラメーターを渡し、jsonリクエストを送信する場合にも、このアプローチを使用できます。
(注:他の将来の読者に役立つように、余分なコードを追加しました)
public void postJsonWithHttpParams() throws URISyntaxException, UnsupportedEncodingException, IOException {
//add the http parameters you wish to pass
List<NameValuePair> postParameters = new ArrayList<>();
postParameters.add(new BasicNameValuePair("param1", "param1_value"));
postParameters.add(new BasicNameValuePair("param2", "param2_value"));
//Build the server URI together with the parameters you wish to pass
URIBuilder uriBuilder = new URIBuilder("http://google.ug");
uriBuilder.addParameters(postParameters);
HttpPost postRequest = new HttpPost(uriBuilder.build());
postRequest.setHeader("Content-Type", "application/json");
//this is your JSON string you are sending as a request
String yourJsonString = "{\"str1\":\"a value\",\"str2\":\"another value\"} ";
//pass the json string request in the entity
HttpEntity entity = new ByteArrayEntity(yourJsonString.getBytes("UTF-8"));
postRequest.setEntity(entity);
//create a socketfactory in order to use an http connection manager
PlainConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> connSocketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainSocketFactory)
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(connSocketFactoryRegistry);
connManager.setMaxTotal(20);
connManager.setDefaultMaxPerRoute(20);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(HttpClientPool.connTimeout)
.setConnectTimeout(HttpClientPool.connTimeout)
.setConnectionRequestTimeout(HttpClientPool.readTimeout)
.build();
// Build the http client.
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(connManager)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
CloseableHttpResponse response = httpclient.execute(postRequest);
//Read the response
String responseString = "";
int statusCode = response.getStatusLine().getStatusCode();
String message = response.getStatusLine().getReasonPhrase();
HttpEntity responseHttpEntity = response.getEntity();
InputStream content = responseHttpEntity.getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = buffer.readLine()) != null) {
responseString += line;
}
//release all resources held by the responseHttpEntity
EntityUtils.consume(responseHttpEntity);
//close the stream
response.close();
// Close the connection manager.
connManager.close();
}
一般的に、HTTP POSTは、本文のコンテンツに、HTML側のフォームによって(ほとんどの場合)作成される一連のキー/値のペアが含まれていることを前提としています。 setHeaderを使用して値を設定しないでください。値をコンテンツ本文に配置しないためです。
したがって、2番目のテストでは、クライアントが複数のキー/値のペアを作成せず、1つしか作成せず、デフォルトでメソッドの最初の引数にマップされるという問題があります。
使用できるオプションがいくつかあります。最初に、1つの入力パラメーターのみを受け入れるようにメソッドを変更してから、2番目のテストで行うようにJSON文字列を渡すことができます。メソッド内に入ると、フィールドへのアクセスを許可するオブジェクトにJSON文字列を解析します。
別のオプションは、入力タイプのフィールドを表すクラスを定義し、それを唯一の入力パラメーターにすることです。例えば
class MyInput
{
String str1;
String str2;
public MyInput() { }
// getters, setters
}
@POST
@Consumes({"application/json"})
@Path("create/")
public void create(MyInput in){
System.out.println("value 1 = " + in.getStr1());
System.out.println("value 2 = " + in.getStr2());
}
使用しているRESTフレームワークに応じて、JSONの逆シリアル化を処理する必要があります。
最後のオプションは、次のようなPOST本文を作成することです。
str1=value1&str2=value2
次に、サーバーメソッドにいくつかの注釈を追加します。
public void create(@QueryParam("str1") String str1,
@QueryParam("str2") String str2)
@QueryParamは、フィールドがフォームポストまたはURL(GETクエリなど)にあるかどうかを気にしません。
入力で個々の引数を引き続き使用する場合、キーはクライアント要求を生成し、URL(GETの場合)またはPOSTの本文で名前付きクエリパラメーターを提供します。