HttpURLConnectionを使ってさくらのサーバーのphpにPOST送信する方法

Android から HttpURLConnection を使って、さくらインターネットの cgi 版 php に HTTP POST 送信する方法です。

Androidアプリケーションを作成することになってHttpURLConnectionを使ってみたけれど、どうもうまくいかないです。 さくらインターネットのレンタルサーバー、スタンダードプランのphpにHTTP POST送信しても値が受け取れません。 検索してみてもPHP側でデータを取得できません。と一蹴されてるだけで具体的な解決策がありませんでした。(Socketを利用するとうまくいきます。とありました)

さくらのレンタルサーバーで値を取得できなかった原因

HttpURLConnectionに渡すパラメーターを調整しながら試行錯誤してみたら、さくらのレンタルサーバーでもphpの$_POSTに値が入るようになりました。phpで値を取得できなかった原因は思いのほか単純で【Transfer-Encoding: chunked】に対応してなかった?だけでした。つまり【Content-Length】を適切に送信してあげるといいことになります。

【setChunkedStreamingMode】を0にするサンプルコードが多すぎてハマったケースです。さくらのphpにスマートフォンからwifi接続すると値が取れず、携帯回線から接続した場合は【503 Service Unavailable】になることが多かったです。phpから標準入力を読み取ってみたりと色々試した結果、【setFixedLengthStreamingMode】の値を設定したらよいことがわかりました。

さくらのレンタルサーバーはお手頃価格ですしユーザーも多いはずなのにAndroidからHttpURLConnectionを使ったHTTP POST送信の例が1つもないのはどうしてでしょう……謎です。

サンプルコード

私はAndroidアプリケーションの開発に手をだしてから3週間程度の素人です。このサンプルコードが参考にならなくても「AndroidからHttpURLConnectionを使ってさくらのphpにHTTP POST送信するには【setFixedLengthStreamingMode】を設定する」と記憶の片隅においておくといいかもしれません。

環境はAndroid 5.1 API22、さくら側はphp5.6(cgi-fcgi)になります。ちなみにHTTP GET送信は一度も試してません。



package net.youyoukankan.www.myapplication;

import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by utsuro on 2016/06/03.
 */
public class HttpPostAsync extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        HttpURLConnection con = null;
        URL url = null;
        String urlStr = "http://example.sakura.ne.jp/receive.php";
        String data = "prefix=sakura&data=レンタルサーバー";
        int length = 0;
        try {
            length = data.getBytes("UTF-8").length;
            Log.d("HTTP_POST", "length: " + length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }

        try {
            url = new URL(urlStr);
            con = (HttpURLConnection) url.openConnection();

            // キャッシュを使用しない
            con.setUseCaches(false);

            // リダイレクトを許可しない
            con.setInstanceFollowRedirects(false);

            // データを読み取る
            con.setDoInput(true);

            // データを書き込む
            con.setDoOutput(true);

            // setDoOutputをtrueにするとPOST送信になるので必要ない
            // con.setRequestMethod("POST");

            // Transfer-Encoding => chunked を使わない
            con.setFixedLengthStreamingMode(length);

            // Transfer-Encoding => chunked を使う
            // con.setChunkedStreamingMode(0);

            // タイムアウト
            con.setReadTimeout(10000);
            con.setConnectTimeout(10000);

            // 接続
            con.connect(); //

            // データの書き込み
            OutputStream out = null;
            try {
                out = con.getOutputStream();
                out.write(data.getBytes("UTF-8"));
                out.flush();
            } catch (IOException e) {
                // POST送信エラー
                e.printStackTrace();
                return null;
            } finally {
                if (out != null) {
                    out.close();
                }
            }

            // ステータスコードの取得
            final int status = con.getResponseCode();
            Log.d("HTTP_POST", "ResponseCode" + status);
            if (status == HttpURLConnection.HTTP_OK) {
                // 正常

                // データの読み取り
                InputStream in = null;
                try {
                    in = con.getInputStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
                    String st = null;
                    while ( (st = br.readLine()) != null) {
                        Log.d("HTTP_POST", st);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (in != null) {
                        in.close();
                    }
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
    }

}


参考サイト

AndroidからGPSのデータを取得しさくらのレンタルサーバーにそのデータをPOST送信しようとして参考にしたサイトです。

シェアする

コメント

トラックバック

トラックバック用URL
http://www.youyoukankan.net/cms/action.php?action=plugin&name=TrackBack&tb_id=173
トラックバック
このエントリにトラックバックはありません