プロジェクトシートK(仮)

技術の吐き溜めなどなど

【Java】POSTメソッドでHTTP通信をする汎用オブジェクト【android】

前回の記事に引き続き、POSTメソッドで通信を行うJavaのオブジェクトを自作してみました。前回の記事はこちら↓↓

konkea.hatenablog.com

内部をちょこっと変えただけなので手抜き感満載ですが、やはり便利なのでいろいろな場面で使えると思います。

仕様一覧

  • 通信をするために用いたライブラリはjava.net
  • インスタンス生成時、コンストラクタ引数にURLオブジェクトを渡してセット
  • HTTPメソッドはPOSTで固定
  • パラメータの付与はメソッドsetParameter(String key, String value)で設定
  • メソッドconnect()で通信を行う. 通信が成功すればtrue, 失敗すればfalseがリターン
  • 接続先が空のオブジェクトを返したときもfalseが返される
  • 通信して取ってきた情報はgetString()により取得可能

コード

import java.io.UnsupportedEncodingException;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class HttpPostObject{
  private URL url;
  private String readSt;
  private List<String> params;

  public HttpPostObject(URL url){
    this.url = url;
    this.readSt = "";
    this.params = new ArrayList<String>();
  }

  public void setParameter(String key, String value){
    if(key.equals("")||value.equals("")) return;
    params.add(key + "=" + value);
    return;
  }

  public boolean connect() {
    HttpURLConnection con = null;
    try {
      con = (HttpURLConnection) url.openConnection();
      con.setRequestMethod("POST");
      con.setInstanceFollowRedirects(false);
      con.setDoOutput(true);

      String parameter = "";
      for(String param : params){
        if(!parameter.equals("")) parameter += "&";
        parameter += param;
      }
      OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(),StandardCharsets.UTF_8);
      out.write(parameter);
      out.flush();
      out.close();

      con.connect();
      int status = con.getResponseCode();
      if (status == HttpURLConnection.HTTP_OK) {
        //コネクト成功
        InputStream in = con.getInputStream();
        readSt = readInputStream(in);
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (con != null) con.disconnect();
    }
    if (readSt.equals("")) return false;
    return true;
  }

  public String getString(){ return this.readSt; }

  private String readInputStream(InputStream in) throws IOException {
    StringBuffer sb = new StringBuffer();
    String st = "";

    BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
    while((st = br.readLine()) != null) sb.append(st);
    try { in.close(); }  catch(Exception e) { e.printStackTrace(); }

    return sb.toString();
  }
}

使用例

import java.net.URL;
import java.net.MalformedURLException;

public class HttpConnectTest {
  public static void main(String args[]){

    try{
      URL url = new URL("https://ほにゃらら");
      HttpPostObject test = new HttpPostObject(url);
      test.setParameter("KEYWORD_1","Value_1");
      test.setParameter("KEYWORD_2","Value_2");
      if(test.connect()){
        System.out.println(test.getString());
      } else {
        System.out.println("Fail HTTP Connect");
      }
    } catch (MalformedURLException e){}
  }
}

オブジェクトHttpPostObjectにURLを付与して生成し、setParameterメソッドでパラメータを付与して通信が行えます。複数パラメータにも対応済み。パラメータか値が空である場合は、setParameterを用いても何も追加されません。

それではHttpPostObjectの詳細を見てみましょう。

解説

コンストラクタ

  public HttpPostObject(URL url){
    this.url = url;
    this.readSt = "";
    this.params = new ArrayList<String>();
  }

見た目通りです。URLオブジェクトを引数に取り、インスタンスフィールドにセットされます。他にもパラメータ設定用の変数paramsを初期化しています。

パラメータのセット

  public void setParameter(String key, String value){
    if(key.equals("")||value.equals("")) return;
    params.add(key + "=" + value);
    return;
  }

2つString型の引数を持ち、keyとvalueに対応させています。いずれかの値に何も文字が入っていなければ ( ""であれば )何もしません。2つの引数が正常に与えられていれば、パラメータ設定用のArrayList型のインスタンスフィールドparamsに「 key "=" value 」という形式で追加します(POSTメソッドの仕様上のため)。

通信

  public boolean connect() {
      .....( 省略 ).....
      con = (HttpURLConnection) url.openConnection();
      con.setRequestMethod("POST");
      con.setInstanceFollowRedirects(false);
      con.setDoOutput(true);

      String parameter = "";
      for(String param : params){
        if(!parameter.equals("")) parameter += "&";
        parameter += param;
      }
      OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(),StandardCharsets.UTF_8);
      out.write(parameter);
      out.flush();
      out.close();

      con.connect();
      .....( 省略 ).....
  }
  • setRequestMethod("POST"); ・・・メソッドの指定。今回はPOST
  • serInstanceFollowRedirects(false); ・・・リダイレクトを無効にする(Stringでページ情報を得るのが目的のため、リダイレクトはそもそも必要ない)。
  • serDoOutput(true); ・・・ POST通信を行う際に必須となる。これがないとパラメータの送信が行えない他、そもそも接続に失敗する。
      String parameter = "";
      for(String param : params){
        if(!parameter.equals("")) parameter += "&";
        parameter += param;
      }

paramsに格納されているパラメータを、1つのString型変数parameterに一括でまとめる。その形式は「key1=value1&key2=value2&...&keyn=valuen」とする(POSTメソッドの仕様上のため)。

  • OutputStreamWriterオブジェクト ・・・パラメータ設定のために必要なアウトプットストリーム。コンストラクタ引数にはHttpURLConnectionオブジェクトのインスタンスメソッドgetOutputStream()と、使用する文字コードを指定する。
  • out.write(parameter); ・・・これでHttpURLConnectionに対するパラメータの付与がされる。
  • out.flush(); ・・・後にBufferWriterに出力するために必要。詳しくは調査不足です(小声)
  • out.close(); ・・・使用済みのストリームはちゃんとcloseしましょう。
  • con.connect(); ・・・設定したパラメータに基づき、HTTP通信が行われます。

まとめ

今回のオブジェクトを使うことで簡単にPOST通信が行えます。また、簡単にパラメータ(複数パラメータもおk)の設定をすることもできます。

しかしながら、オブジェクトを使用するためにjava.net.URLなどのライブラリをインポートする必要があったり、例外処理をしなくてはいけなかったりとやけに中途半端になってしまいました。そこで次回の記事では、GETメソッドとも一緒に「極限まで使いやすくしたHttpConnectオブジェクト」を作ってみようと思います。一行の記述で通信が行えるくらいを目標に作りたいです。

おしまい。