URLConnection(HttpURLConnection)と向き合うために、今回はPOSTメソッドを使います。
POSTはPOSTでも特にHTMLのフォームタグでPOSTを行ったときと同様のデータを送信します。
今回の目標
- HttpURLConnectionを使ってPOSTメソッドを行う。
- ContentTypeはapplication/x-www-form-urlencodedの形式にする。
- POSTメソッドのレスポンスデータを取得する。
HttpURLConnectionを使ったPOSTのやり方
HttpURLConnection はGET/POSTに関係なくメソッドの呼び出し順序は大体決まっています。
順序は下記のとおりです。
順序は下記のとおりです。
- ステップ1 :接続URLを決める。
- ステップ2 :URLへのコネクションを取得する。
- ステップ3 :接続設定(メソッドの決定,タイムアウト値,ヘッダー値等)を行う。
- ステップ4 :コネクションを開く
- ステップ5 :リクエストボディの書き込みを行う。(POSTのみ行う)
- ステップ6 :レスポンスの読み出しを行う。
- ステップ7 :コネクションを閉じる。
ステップ1:接続URLを決める。
URL url = new URL("[接続先のURLを設定してください。]");
ステップ2:URLへのコネクションを取得する。
URL url = [ステップ1:接続URLを決めるを参照してください]; HttpURLConnection urlConnection = null; try { urlConnection = (HttpURLConnection) url.openConnection(); } catch (IOException e) { e.printStackTrace(); }
ステップ3:接続設定(メソッドの決定,タイムアウト値,ヘッダー値等)を行う。
- setRequestMethod を使いPOSTを使う設定をする
- リクエストボディの Content-Type を application/x-www-form-urlencoded に設定する。
- リクエストボディにデータを書き込むため、setDoOutput を使い許可をする。
- レスポンスボディのデータを読み出しするため、setDoInput を使い許可をする。
//接続タイムアウトを設定する。 urlConnection.setConnectTimeout(100000); //レスポンスデータ読み取りタイムアウトを設定する。 urlConnection.setReadTimeout(100000); //ヘッダーにUser-Agentを設定する。 urlConnection.setRequestProperty("User-Agent", "Android"); //ヘッダーにAccept-Languageを設定する。 urlConnection.setRequestProperty("Accept-Language", Locale.getDefault().toString()); //ヘッダーにContent-Typeを設定する urlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //HTTPのメソッドをPOSTに設定する。 urlConnection.setRequestMethod("POST"); //リクエストのボディ送信を許可する urlConnection.setDoOutput(true); //レスポンスのボディ受信を許可する urlConnection.setDoInput(true);
ステップ4:コネクションを開く
このメソッド以降は「接続先にデータを送信する OutputStream 」と「接続先からデータを受信する InputStream 」を使うことができるようになります。
//ステップ4.コネクションを開く urlConnection.connect();
ステップ5:リクエストボディの書き込みを行う。
また、key と value はそれぞれURLエンコードする必要があります。そのため Uri.Builder クラスを使い送信文字列を作成します。
書き込みが終わったら必ずストリームを閉じましょう。
//ステップ5:リクエストボディの書き出しを行う。 OutputStream outputStream = urlConnection.getOutputStream(); HashMapkeyValues = new HashMap<>(); keyValues.put("key" , "value"); if (keyValues.size() > 0) { Uri.Builder builder = new Uri.Builder(); //HashMapを[key=value]形式の文字列に変換する Set keys = keyValues.keySet(); for (String key : keys) { //[key=value]形式の文字列に変換する。 builder.appendQueryParameter(key , keyValues.get(key); } //[key=value&key=value…]形式の文字列に変換する。 String join = builder.build().getEncodedQuery(); PrintStream ps = new PrintStream(outputStream); ps.print(join); ps.close(); } outputStream.close();
ステップ6:レスポンスボディの読み出しを行う。
主なレスポンスデータは下記のメソッドを使って取得します。
- getResponseCode を使うことでHTTPステータスコードを取得できます。
- getInputStream を使うことレスポンスボディのデータストリームを取得できます。
//ステップ6:レスポンスボディの読み出しを行う。 int statusCode = urlConnection.getResponseCode(); String responseData = ""; InputStream stream = urlConnection.getInputStream(); StringBuffer sb = new StringBuffer(); String line = ""; BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8")); while ((line = br.readLine()) != null) { sb.append(line); } try { stream.close(); } catch (Exception e) { e.printStackTrace(); } responseData = sb.toString();
今回はレスポンスボディのデータストリームを文字列に変換しています。
ステップ7:コネクションを閉じる。
使ったコネクションはしっかりと閉じましょう。
//ステップ7:コネクションを閉じる。 urlConnection.disconnect();
サンプルコード
- URLとハッシュマップを引数で渡す。
- 指定したURLにPOSTメソッドで接続する。
- Content-Typeはapplication/x-www-form-urlencodeを使用する。
- リクエストボディにハッシュマップからapplication/x-www-form-urlencodeに適合する文字列を生成し送信する。
- レスポンスボディデータは文字列として扱う。
- 非同期処理から呼び出されることを想定している。
- 呼び出し側には文字列を返却する。
public String execute(String argStrApiUrl, HashMap<String,string> formItems) { String ret = ""; HttpURLConnection urlConnection = null; try { //ステップ1.接続URLを決める。 URL url = new URL(argStrApiUrl); //ステップ2.URLへのコネクションを取得する。 urlConnection = (HttpURLConnection) url.openConnection(); //ステップ3.接続設定(メソッドの決定,タイムアウト値,ヘッダー値等)を行う。 //接続タイムアウトを設定する。 urlConnection.setConnectTimeout(100000); //レスポンスデータ読み取りタイムアウトを設定する。 urlConnection.setReadTimeout(100000); //ヘッダーにUser-Agentを設定する。 urlConnection.setRequestProperty("User-Agent", "Android"); //ヘッダーにAccept-Languageを設定する。 urlConnection.setRequestProperty("Accept-Language", Locale.getDefault().toString()); //ヘッダーにContent-Typeを設定する urlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //HTTPのメソッドをPOSTに設定する。 urlConnection.setRequestMethod("POST"); //リクエストのボディ送信を許可する urlConnection.setDoOutput(true); //レスポンスのボディ受信を許可する urlConnection.setDoInput(true); //ステップ4.コネクションを開く urlConnection.connect(); //ステップ5:リクエストボディの書き出しを行う。 OutputStream outputStream = urlConnection.getOutputStream(); if (formItems.size() > 0) { Uri.Builder builder = new Uri.Builder(); Setkeys = formItems.keySet(); for (String key : keys) { //[key=value&key=value…]形式の文字列に変換する。 builder.appendQueryParameter(key , formItems.get(key)); } String join = builder.build().getEncodedQuery(); PrintStream ps = new PrintStream(outputStream); ps.print(join); ps.close(); } outputStream.close(); //ステップ6.レスポンスボディの読み出しを行う。 int responseCode = urlConnection.getResponseCode(); ret = convertToString(urlConnection.getInputStream()); Log.d("execute", "URL:" + argStrApiUrl); Log.d("execute", "HttpStatusCode:" + responseCode); Log.d("execute", "ResponseData:" + ret); } catch (IOException e) { e.printStackTrace(); } finally { if (urlConnection != null) { //7.コネクションを閉じる。 urlConnection.disconnect(); } } return ret; } public String convertToString(InputStream stream) throws IOException { StringBuffer sb = new StringBuffer(); String line = ""; BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8")); while ((line = br.readLine()) != null) { sb.append(line); } try { stream.close(); } catch (Exception e) { e.printStackTrace(); } return sb.toString(); }
今回のまとめ
- POSTメソッドではリクエストボディを使ったデータ送信を許可するために setDoOutput にtrueを渡すこと。
- application/x-www-form-urlencoded に適合した送信文字列を作成するときは Uri.Builder クラスを使用すること。
- テキストとファイルを同時に送信する Content-Type「multipart/form-data」とは異なるので注意すること。
android
0 件のコメント:
コメントを投稿