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

技術の吐き溜めなどなど

【Java】GETメソッドでHTTP通信をする汎用オブジェクトを自作してみた 【android】

プログラミングにおいて"通信をすること"はめちゃくちゃ大事な要素です。
その通信手法にはTCP/IPであったりHTTPであったり、はたまたP2Pであったりと多種多様のものが存在します。

前回の記事では「Webサーバ」について触れさせていただきました。WebサーバではHTTP通信を用いてクライアントとサーバ同士を通信させています。

では、そのようなHTTP通信を行うためには何が必要なのでしょうか。今回の記事ではJavaクライアントからHTTP通信を行うというシチュエーションで、便利な汎用オブジェクトを紹介したいと思います。

仕様一覧

- 通信をするために用いたライブラリはjava.net

- インスタンス生成時、コンストラクタ引数にURLオブジェクトを渡してセット

- HTTPメソッドはGETで固定

- メソッドconnect()で通信を行う. 通信が成功すればtrue, 失敗すればfalseがリターン

- 接続先が空のオブジェクトを返したときもfalseが返される

- 通信して取ってきた情報はgetString()により取得可能

- 文字列エンコーディングは曖昧 ( 誰か教えて下さいw )

コード

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

public class HttpGetObject{
  private URL url;
  private String readSt;

  public HttpGetObject(URL url){
    this.url = url;
    this.readSt = "";
  }

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

      int status = con.getResponseCode();
      if (status == HttpURLConnection.HTTP_OK) {
        //コネクト成功
        InputStream in = con.getInputStream();
        readSt = readInputStream(in);
      }
    } catch (IOException e) {
      //コネクト失敗
    } 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://www.google.co.jp");
      HttpGetObject obj = new HttpGetObject(url);
      if(obj.connect()){
        System.out.println(obj.getString());
      } else {
        System.out.println("Fail HTTP Connection");
      }
    } catch (MalformedURLException e){
      //接続失敗
    }
  }
}

使用例を見ればある程度分かると思いますが、このオブジェクトによりhttp通信がかなり楽に行えます。本来「http通信をJavaでしよう!」となると

"HttpURLConnectionオブジェクト作って、URLオブジェクトからコネクションを確立させて、メソッド指定して、色々設定して..."

みたいに、結構面倒な手続きが必要なんですよね。ライブラリのインポートとか出力の取得とかもなかなか面倒。そこで、ある程度使用する機能を絞ることによって ( 今回の場合はGETメソッドのみを使うこと ) 記述を楽にできました。

ぶっちゃけた話

try{
  HttpGetObject obj = new HttpGetObject(new URL("http://..."));
  if(obj.connect()) System.out.println(obj.getString());
} catch (MalformedURLException e){}

これだけで接続できます。 ( ライブラリのインポートは必要! )

このオブジェクトの使いどころですが、例えばWebアプリケーションを使う際に、サーバのデータベースからデータリストをJSONで返すことにすれば、JavaクライアントでJSON文字列を取得でき、自由でにデータを処理することができるでしょう。

JavaJSON文字列を処理するためのライブラリもありますから、そう難しいことではないはず。

まとめ

JavaによるGETメソッド専用のHTTP通信オブジェクトができました。
使い方さえ把握できればめちゃくちゃ記述が楽になります。

また、同様にPOST専用の HTTP通信オブジエクトも作ることができます。これに関してはまた別の記事で紹介しましょう。

補足

今回作成したオブジェクトは、記述を更に簡単にすることができます。
今回はコンストラクタの引数にURLオブジェクトを渡しましたが、これをString文字列で渡すようにも設計できます。そうすれば、呼び出し側のプログラムでライブラリのインポートが必要なくなるし、例外処理も要らなくなるでしょう ( 要検証 ) 。
しかしながらかなり抽象的な記述になってしまうために、Javaで使うのであれば避けるべきなのかなぁと個人的に引っかかっています。この辺のお話も、また別の記事で軽く紹介しようと思います。