Java で HTTP クライアントを作ってみよう (2)

前へ << Java で HTTP クライアントを作ってみよう (1) Java で HTTP クライアントを作ってみよう (3) >> 次へ

HttpURLConnection クラス

Socket クラスでごりごり書くのも悪くはないですが、 実際に使用するプログラムを書くとなると結構つらいものがあります。 より便利な HttpURLConnection クラスが用意されていますので、これを使ってみましょう。
% javac HttpClientHttpURLConnection.java
とコンパイルすることで HttpClientHttpURLConnection.class が生成され、
% java HttpClientHttpURLConnection
で実行できます。このプログラムは http://www.debian.org/ にアクセスし、 以下のような出力を行います。
レスポンスヘッダ:
  ETag: ["233112-3ea9-42284510;422847e3"]
  Date: [Sat, 05 Mar 2005 11:54:18 GMT]
  Content-Type: [text/html]
  null: [1.1 200 OK]
(略)
  Content-Location: [index.ja.html]
  Vary: [negotiate,accept-language]
レスポンスコード[200] レスポンスメッセージ[OK]

---- ボディ ----
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
  <title>Debian -- ユニバーサルオペレーティングシステム</title>
(略)

ソース

HttpClientHttpURLConnection.java

    1: import java.net.*;
    2: import java.io.*;
    3: import java.util.*;
    4: 
    5: /**
    6:  * Java HTTP クライアントサンプル - HttpURLConnection 版 -
    7:  *
    8:  * @author 68user http://X68000.q-e-d.net/~68user/
    9:  */
   10: public class HttpClientHttpURLConnection {
   11:     public static void main(String[] args)
   12:         throws MalformedURLException, ProtocolException, IOException {
   13: 
   14:         URL url = new URL("http://www.debian.org/");
   15: 
   16:         HttpURLConnection urlconn = (HttpURLConnection)url.openConnection();
   17:         urlconn.setRequestMethod("GET");
   18:         urlconn.setInstanceFollowRedirects(false);
   19:         urlconn.setRequestProperty("Accept-Language", "ja;q=0.7,en;q=0.3");
   20: 
   21:         urlconn.connect();
   22: 
   23:         Map headers = urlconn.getHeaderFields();
   24:         Iterator it = headers.keySet().iterator();
   25:         System.out.println("レスポンスヘッダ:");
   26:         while (it.hasNext()){
   27:             String key= (String)it.next();
   28:             System.out.println("  " + key + ": " + headers.get(key));
   29:         }
   30: 
   31:         System.out.println("レスポンスコード[" + urlconn.getResponseCode() + "] " +
   32:                            "レスポンスメッセージ[" + urlconn.getResponseMessage() + "]");
   33:         System.out.println("\n---- ボディ ----");
   34: 
   35:         BufferedReader reader =
   36:             new BufferedReader(new InputStreamReader(urlconn.getInputStream()));
   37: 
   38:         while (true){
   39:             String line = reader.readLine();
   40:             if ( line == null ){
   41:                 break;
   42:             }
   43:             System.out.println(line);
   44:         }
   45: 
   46:         reader.close();
   47:         urlconn.disconnect();
   48:     }
   49: }

ソース解説

   14:         URL url = new URL("http://www.debian.org/");
URL オブジェクトを生成します。もし URL として不正な文字列を渡した場合は、 MalformedURLException が発生します。
   16:         HttpURLConnection urlconn = (HttpURLConnection)url.openConnection();
   17:         urlconn.setRequestMethod("GET");
   18:         urlconn.setInstanceFollowRedirects(false);
   19:         urlconn.setRequestProperty("Accept-Language", "ja;q=0.7,en;q=0.3");
URL#openConnection メソッドを呼び、HttpURLConnection オブジェクトを取得します。 そして以下の設定を行います。
  • setRequestMethod メソッドで、HTTP の GET メソッドを設定します。 ここでもし変な文字列を渡すと ProtocolException が発生します。
  • setInstanceFollowRedirects メソッドに false を指定することで、 レスポンスが 3xx であっても、 指定されたリダイレクトに従わないようにします。
  • setRequestProperty メソッドで、Accept-Language をセットします。ここでは日本語を英語より優先度を高くしています。 http://www.debian.orgコンテントネゴシエーション を利用しており、 同一 URL であっても Accept-Language の値によって異なる内容を返します (例: 日本語ページ英語ページ)。
この他に User-Agent など指定したいヘッダがあれば、さらに setRequestProperty メソッドを使って設定できます。
   21:         urlconn.connect();
www.debian.org のサーバに接続します。 このメソッドから帰ってきた時点で、既にサーバからのレスポンスは届いています。
   23:         Map headers = urlconn.getHeaderFields();
   24:         Iterator it = headers.keySet().iterator();
   25:         System.out.println("レスポンスヘッダ:");
   26:         while (it.hasNext()){
   27:             String key= (String)it.next();
   28:             System.out.println("  " + key + ": " + headers.get(key));
   29:         }
   30: 
   31:         System.out.println("レスポンスコード[" + urlconn.getResponseCode() + "] " +
   32:                            "レスポンスメッセージ[" + urlconn.getResponseMessage() + "]");
   33:         System.out.println("\n---- ボディ ----");
Content-Type などのレスポンスヘッダと、レスポンスコード・レスポンスメッセージ (200・OK など) を表示します。ここでは全ヘッダを表示していますが、主要なヘッダであれば HttpURLConnection クラスの getContentType・getDate などのメソッドが使えます。

ここでは HttpURLConnection#getHeaderFields メソッドを使っていますが、 これは Java 1.4 から実装されたメソッドです。Java 1.3 系以前をお使いの方は、 上記のソースをコメントアウトしてください。


   35:         BufferedReader reader =
   36:             new BufferedReader(new InputStreamReader(urlconn.getInputStream()));
   37: 
   38:         while (true){
   39:             String line = reader.readLine();
   40:             if ( line == null ){
   41:                 break;
   42:             }
   43:             System.out.println(line);
   44:         }
HttpURLConnection#getInputStream メソッドを使って、InputStream オブジェクトを取得します。 さらに InputStramReader クラスと BufferedReader クラスを経由して 1行ずつデータを取得します。 Socket クラスを使ったときと異なり、ここではボディ部しか取得できないことに注意してください。
   46:         reader.close();
   47:         urlconn.disconnect();
後始末として、BufferedReader と HttpURLConnection をクローズします。

HttpURLConnection のメリット

このサンプルだけでは HttpURLConnection のメリットはそれほど感じられないかもしれません。 しかし SSL/TLS・レスポンスコード 3xx 系への対応・Basic 認証や Digest 認証などが絡んでくると、 この手のクラスはやはり楽だなぁと感じることでしょう。

次節でそれを実感していただきます。

前へ << Java で HTTP クライアントを作ってみよう (1) Java で HTTP クライアントを作ってみよう (3) >> 次へ

ご意見・ご指摘は Twitter: @68user までお願いします。