HTTPでGETが出来たので、今度は実際に品番を入れてサーバ側に問い合わせを行ってみようかと思います。先のプログラムを基にGETではなくPOSTで品番をサーバに送るようにしてみました。サーバからの返信はHTML形式ではなく、解析が容易なJSON形式で受け取るようにしています(JSON形式はStruts2に用意されているJSON Resultを使用)。今回は配列タイプのJSONのみを使っているので["value1","value2","value3",....]のような簡単な書式の文字列が返されます。
サーバから受け取ったCookieを保存するListを加えました。検索ボタンが押下された時の処理ハンドラを登録します。入力された品番を引数に検索処理を呼び出し、例外が発生した場合はアラート表示します。品番が未入力の場合は例外を発生させてアラート表示させます。
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.mSavedCookies = new ArrayList<Cookie>(); // Button Click Listenerの設定 Button btn = (Button) this.findViewById(R.id.btnSearch); btn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View view) { String result = ""; try { // 入力した品番を取得 EditText edit1 = (EditText) findViewById(R.id.txtHinban); String hinban = ((SpannableStringBuilder) edit1.getText()).toString().trim(); if (hinban.length() == 0) throw new Exception("品番を入力してください。"); // HTTP通信処理で品番を検索 result = doSearch(hinban); } catch (Exception ex) { // 例外が発生した場合はアラート表示する AlertDialog.Builder dlg; dlg = new AlertDialog.Builder(MainActivity.this); dlg.setTitle("Error"); dlg.setMessage(ex.getLocalizedMessage()); dlg.show(); } // 取得した品番情報を表示 EditText edit2 = (EditText) findViewById(R.id.txtResult); edit2.setText(result); } }); }
HTTP通信(POSTコマンド)の核部分です。引数のactionはStruts2のaction名(ex: start.actionなど)を指定します。post_paramsにはサーバに送るPOSTデータのパラメータ名と値のペアが格納された配列を渡します。
private String doPost(String action, List<NameValuePair> post_params) {
HTTP通信用の各種パラメータは参照サイトよりコピペさせて頂いているので、詳細はまた後日調べようかと、、、尚、encodeは文字列定数で"UTF-8"が定義してあります。
// HttpClientの構築 SchemeRegistry schreg = this.getSchem(); HttpParams params = this.getHttpParams(); ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager(params, schreg);
HTTPクライアントを作成しています。前回受け取ったCookieを再度設定してサーバに渡すようにしています(サーバ側のセッション維持用)。
DefaultHttpClient client = new DefaultHttpClient(connManager, params); // 退避しておいたcookieを代入する for (Cookie cookie : this.mSavedCookies) { client.getCookieStore().addCookie(cookie); }
POST要求を実行します。appurlはStruts2のWebアプリケーションへのベースURL文字列定数です(ex: "http://localhost:8080/WebAndroidApp/")。これに実行したいactionを加えます。又、引数で指定されたPOST用のデータもここで渡しています。
try { // POST要求生成 HttpPost request = new HttpPost(appurl + action); // POSTデータの設定 request.setEntity(new UrlEncodedFormEntity(post_params, encode)); // Handlerを使って実行 String result = client.execute(request, new ResponseHandler<String>() { @Override public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException { // 実行結果の確認 switch (response.getStatusLine().getStatusCode()) { case HttpStatus.SC_OK: // Response内容を取得して表示 String msg = EntityUtils.toString(response.getEntity(), encode); return msg; case HttpStatus.SC_NOT_FOUND: throw new RuntimeException("Error: Not Found"); default: throw new RuntimeException("Error: something"); } } });
次回の通信の為に受信したCookieを退避させてから、結果を返す。
// 取得したcookieを退避 this.saveCookie(client); return result;
例外処理と最終処理
} catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } catch (ClientProtocolException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { client.getConnectionManager().shutdown(); } }
private SchemeRegistry getSchem() { SchemeRegistry schreg = new SchemeRegistry(); schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schreg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); return schreg; } private HttpParams getHttpParams() { HttpParams params = new BasicHttpParams(); HttpConnectionParams.setSocketBufferSize(params, 4096); //ソケットバッファサイズ 4KB HttpConnectionParams.setSoTimeout(params, 20000); //ソケット通信タイムアウト20秒 HttpConnectionParams.setConnectionTimeout(params, 20000); //HTTP通信タイムアウト20秒 HttpProtocolParams.setContentCharset(params, encode); //文字コードをUTF-8と明示 HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); //HTTP1.1 return params; }
以前のCookie退避配列をクリアして、今回サーバから送られてきたCookieを配列に追加しているだけです。
private void saveCookie(DefaultHttpClient client) { this.mSavedCookies.clear(); List<Cookie> cookies = client.getCookieStore().getCookies(); for (Cookie cookie : cookies) { this.mSavedCookies.add(cookie); } }
引数の品番でPOST用のデータ(パラメータ)を作成し、actionに検索action名を指定してPOST実行処理を呼び出しています。
結果はJSON形式の文字列として返るので、parseJsonにて文字列の配列に変換しています。2番目の要素に結果のステータスが返り、成功していれば3番目の要素に品名が格納されえいます。1番目の要素は"Json"という文字列が必ず入っている固定要素です。これらの戻り値の構成は全てWebアプリケーション側で行われています。
private String doSearch(String hinban) throws Exception { List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("hinban",hinban)); List<String> result = this.parseJson(this.doPost("search.action", params)); String status = result.get(1); if (status.equals(MSG_SEARCH_SUCCESS)) return result.get(2); else throw new Exception("指定の品番に該当がありませんでした。"); }
原始的ではありますが、一応原型らしきものができました。
次回はサーバ側の紹介をしていこうかと思います。