javaのHttpClientでリクエストをPOST(タイムアウト設定付き)

以前、「Apache HttpComponents」プロジェクトの「HttpClient」を利用して、GETメソッドでリクエストを投げて、結果を取得する方法の記事を書きましたが、今回は、POST編です。

別の接続先にPOSTでリクエストを投げて、XMLで結果を受け取ることになったので、その方法をメモしておきます。

今回のPOSTのソースで出来ることの概要

今回の記事では、POST部分にフォーカスしてコードを載せてあります。proxy経由でのWebアクセスや、BASIC認証のやり方は、そのGETの記事に書いてありますので、そちらを参考にしてください。

javaのHttpClientでファイルをダウンロード(proxy経由とBASIC認証付き)javaのHttpClientでファイルをダウンロード(proxy経由とBASIC認証付き)

その代わり、今回は接続時のコネクションタイムアウトの設定を考慮したソースにしました。

接続先のサーバが何かしらの理由で反応しない場合、こちらのプログラムも反応が返るまで待ってしまうことになります。先方で接続を切ってくれればいいのですが、そうとも限らないため、一定時間待ったら、コネクションを切断して、制御をこちら側のプログラムに戻すことにしましょう。

では、今回も以下に簡単なサンプルを載せておきます。

サンプルソースの下の方に簡単に説明(ポイント)を付けておきますので、ぜひ読んでください。

2016年12月追記

この方法はApacheのライブラリを使います。

別に、Javaの標準クラス「HttpURLConnection」を使った方法もあり、場合によってはそちらの方がシンプルで良いという人もいるかもしれません。

その方法については、以下に記事を書きましたので、そちらを参考にしてください。

まずは、ライブラリを用意する必要がありますね。これも、前回記事の「HttpClientパッケージを用意」の項目を参考にしていただけると。

サンプルソースとポイント

では、サンプルのソースです。

import java.util.ArrayList;
 
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
 
public class HttpPostConnect {
 
    private static final String TARGET_HOST = "http://xxxxxxxxxx:8080/Search";
 
    public final static void main(String[] args) throws Exception {
 
    DefaultHttpClient httpclient = null;
    HttpPost post = null;
    HttpEntity entity = null;
 
        try {
            httpclient = new DefaultHttpClient();
 
            HttpParams httpParams = httpclient.getParams();
            //接続確立のタイムアウトを設定(単位:ms)
            HttpConnectionParams.setConnectionTimeout(httpParams, 500*1000);
            //接続後のタイムアウトを設定(単位:ms)
            HttpConnectionParams.setSoTimeout(httpParams, 500*1000);
 
            post = new HttpPost(TARGET_HOST);
            post.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
 
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("query", "aaaaaaa"));
            post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
 
            final HttpResponse response = httpclient.execute(post);
 
            // レスポンスヘッダーの取得(ファイルが無かった場合などは404)
            System.out.println("StatusCode=" + response.getStatusLine().getStatusCode());
 
            if(response.getStatusLine().getStatusCode() != 200 ){
 
                System.out.println("StatusCode:" + response.getStatusLine().getStatusCode());
                return;
            }
 
            entity = response.getEntity();
 
            // entityが取れなかった場合は、Connectionのことは心配しないでもOK
            if (entity != null) {
 
                System.out.println(EntityUtils.toString(entity));
 
                System.out.println("length: " + entity.getContentLength());
 
                EntityUtils.consume(entity);
                //depriciated
                entity.consumeContent();
                post.abort();
            }
 
            System.out.println("結果を取得しました。");
 
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            httpclient.getConnectionManager().shutdown();
        }
    }
}

タイムアウト設定について

上記のソースでは、

HttpConnectionParams.setConnectionTimeout(httpParams, 500*1000);

HttpConnectionParams.setSoTimeout(httpParams, 500*1000);

の2つのタイムアウトを設定しています。2つとも接続に関する設定なのですが、以下の違いがあります。

setConnectionTimeout・・・接続が確立するまでの時間をミリ秒で設定します。サーバ側の負荷が高い場合、接続させてくれるまでに待つことになりますが、それをあきらめるまでの時間です。

setSoTimeout・・・接続後、データを取得する時間をミリ秒で設定します。サーバ側の負荷が高く、接続後もなかなかデータを返せない場合(DB待ちなど)に、それをあきらめるまでの時間です。

以下がPOSTのパラーメータをセットしている部分です。

ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();

params.add(new BasicNameValuePair(“query”, “aaaaaaa”));

上記は”query”というパラメータ名で”aaaaaaa”という値をセットしています。

他にパラメータがある場合は、params.addでどんどん追加していきましょう。

entity.consumeContent();

はdepriciatedになっています。EntityUtilsクラスのconsumeメソッドを利用しましょう。