package com.android_mvc.framework.net;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
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.util.EntityUtils;
import com.android_mvc.framework.common.FWUtil;
/**
* 同期的なHTTP通信を行うクラス。
* @author id:language_and_engineering
*
*/
public class HttpPostRequest
{
// NOTE: 下記を参考に。
// http://d.hatena.ne.jp/language_and_engineering/20111121/p1
// NOTE: 全BLは,自動的に別スレッド上で同期的に実行される。
// なので,過去バージョンが持っていた「逐次実行可能性」の性質は除去した。
// ダイアログも不要になり,きわめてシンプルになった。
// TODO: httpsとかGETに対応
// 設定事項
private String request_encoding = "UTF-8";
private String response_encoding = "UTF-8";
// 事前
private String target_url;
private List<NameValuePair> post_params = new ArrayList<NameValuePair>();
// 事後
HttpPostResponse res = new HttpPostResponse();
/**
* アクセス対象のURLをセット
*/
public HttpPostRequest target(String url)
{
this.target_url = url;
FWUtil.d("this.target_urlにセット:" + this.target_url);
return this;
}
/**
* POSTパラメータを追加
*/
public HttpPostRequest addParam(String post_name, String post_value)
{
post_params.add(new BasicNameValuePair( post_name, post_value ));
FWUtil.d(
"POSTパラメータ名「"
+ post_name
+ "」,値「"
+ post_value
+ "」をセット。"
);
return this;
}
/**
* リクエストを送信し,通信結果を返す。
*/
public HttpPostResponse getResponse()
{
if(target_url == null)
{
FWUtil.e("URLがセットされていません。");
return null;
}
FWUtil.d("post実行します");
// URL
URI urlObj;
try {
urlObj = new URI( target_url );
FWUtil.d("URLはOK");
} catch (URISyntaxException e) {
e.printStackTrace();
return res.err( "不正なURL" );
}
// POSTパラメータ付きでPOSTリクエストを構築
HttpPost request = new HttpPost( urlObj );
try {
// 送信パラメータのエンコードを指定
request.setEntity(new UrlEncodedFormEntity(post_params, request_encoding));
FWUtil.d( "文字コードはOK" );
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return res.err( "不正な文字コード" );
}
// POSTリクエストを実行
DefaultHttpClient httpClient = new DefaultHttpClient();
FWUtil.d("POST開始");
try {
// 通信を同期的に実行し,handlerにHttpResponseを操作させる
httpClient.execute( request, response_handler );
} catch (ClientProtocolException e) {
e.printStackTrace();
return res.err( "プロトコルのエラー" );
} catch (IOException e) {
e.printStackTrace();
return res.err( "IOエラー" );
}
// shutdownすると通信できなくなる
httpClient.getConnectionManager().shutdown();
return res;
}
/**
* 通信結果を受理して結果を返すためのハンドラ
*/
private ResponseHandler<Void> response_handler = new ResponseHandler<Void>() {
// HTTPレスポンスから,受信文字列をエンコードして文字列として返す
@Override
public Void handleResponse(HttpResponse response) throws IOException
{
int response_code = response.getStatusLine().getStatusCode();
FWUtil.d( "レスポンスコード:" + response_code );
// 成否で場合分け
switch ( response_code )
{
// 正常に受信できた場合は200
case HttpStatus.SC_OK:
FWUtil.d("レスポンス取得に成功");
// レスポンスデータをエンコード済みの文字列として取得する。
// ※IOExceptionの可能性あり
String response_text = EntityUtils.toString(
response.getEntity(),
HttpPostRequest.this.response_encoding
);
res.setTextOnSuccess( response_text );
break;
// 404
case HttpStatus.SC_NOT_FOUND:
FWUtil.d("存在しない");
res.err( "404 Not Found" );
break;
default:
FWUtil.d("通信エラー");
res.err( "通信エラーが発生" );
}
return null;
}
};
}