Previous | Next | Trail Map | Custom Networking and Security | URL を扱う


URLConnection を読み書きする

openConnection() を使用して正常に URL との通信を開始できたなら 、ユーザは URLConnection オブジェクトへの参照をもっていることになる。 URLConnection クラスは、ネットワークを通じて URL と通信するための多数のメソ ッドをもっている。URLConnection は HTTP 中心のクラスであり、そのメソッドの多 くは HTTP URL を扱っている場合にのみ有効である。 ただし、ほとんどの URL プロトコルではコネクションへの読み書きができるため、 このページでは URLConnection オブジェクトを通して URL からの読み取りと URL への書き込みを行う両方の方法について説明する。

URLConnection から読み取る

以下に示すプログラムは、 URL から直接読み取るで示したプログラムと同じ働 きをする。ただし、URL から直接ストリームを開くのではなく、このプログラムは URL へのコネクションを明示的に開き、そのコネクションで入力ストリームを獲得し 、その入力ストリームから読み取るようになっている。

import java.net.*;
import java.io.*;

class ConnectionTest {
    public static void main(String[] args) {
        try {
            URL yahoo = new URL("http://www.yahoo.com/");
            URLConnection yahooConnection = yahoo.openConnection();
            DataInputStream dis = new 
DataInputStream(yahooConnection.getInputStream());
            String inputLine;

            while ((inputLine = dis.readLine()) != null) {
                System.out.println(inputLine);
            }
            dis.close();
        } catch (MalformedURLException me) {
            System.out.println("MalformedURLException: " + me);
        } catch (IOException ioe) {
            System.out.println("IOException: " + ioe);
        }
    }
}

このプログラムの出力は URL から直接ストリームを開くプログラムのものと同じは ずである。URL からの読み取りにはどちらの方法を使用してもよい。 しかし、 URLConnection オブジェクトは同時に別のタスク (URL へ書き込むなど) にも利用で きるので、URL から直接読み取るよりも URLConnection から読み取る方が便利な場 合もある。

ここでも、プログラムからの出力の代わりに次のようなエラーメッセージが表示され ることがあある。

IOException: java.net.UnknownHostException: www.yahoo.com

この場合は、プログラムが www.yahoo.com サーバを見つけるためにユーザが proxy ホストを設定しなければならないことが考えられる。

URLConnection に書き込む

多くの HTML ページにはフォームが使われている。フォームは、ユーザがサーバにデー タを入力するための、テキストフィールドやその他の GUI オブジェクトである。必 要な情報を入力し、ボタンのクリックによって問い合わせを開始すると、使用中の Web ブラウザがネットワークを通じて URL にデータを書き込んでくれる。先方では 、(通常は) サーバ上の cgi-bin スクリプトがデータを処理し、通常は新たな HTML ページの形で応答を返信する。このシナリオは検索のサポートによく利用されている 。

多くの cgi-bin スクリプトは、クライアントからのデータの読み取りに POST METHOD を使用している。このため URL へ書き込むことはURL へポストする と言うことも多い。POST METHOD を使用するサーバ側のスクリプトは標準入力 から読み取りを行う。


注: サーバ側の cgi-bin スクリプトの中には GET METHOD を使用してデータを読み取る ものもある。しかし、POST METHOD の方が用途が広く、コネクションを通じて送信で きるデータ量にも制限がないため、GET METHOD は使われなくなってきている。

Java プログラムはサーバ側の cgi-bin スクリプトと対話することもできる。 URL へ書き込めるようにしておくだけで、データがサーバに送られる。 プログラムでは以下のステップによってこの機能を実現できる。

  1. URL を作成する。
  2. URL へのコネクションを開く。
  3. コネクションから出力ストリームを得る。 この出力ストリームはサーバ上の cgi-bin スクリプトの標準入力に接続している。
  4. 出力ストリームに書き込む。
  5. 出力ストリームを閉じる。

Java チームのメンバの 1 人、ハッサン・シュローダーは、 backwards という名前の簡単な cgi-bin スクリプトを作成し、それを当社の Web サイト、 java.sun.com で利用できるようにした。読者はこのスクリプトを使っ て、以下に示すプログラム例をテストすることができる。何らかの理由で当社の Web サイトをアクセスできない場合は、読者のネットワークのどこかに backwards という名前でこのスクリプトを置けばローカルにプログラ ムをテストできる。

当社の Web サイトでこのスクリプトは、標準入力から文字列を読み取り、その文字 列を逆にし、結果を標準出力に書き込むようになっている。このスクリプトでは、入 力の書式が string=string_to_reverse でなければならな い。この、string_to_reverse には文字の順序を逆にして表 示させたい文字列を指定する。

URLConnection を通してネットワーク上で backwards スクリプトを実 行するプログラム例を次に示す。

import java.io.*;
import java.net.*;public class ReverseTest {
    public static void main(String[] args) {
        try {
            if (args.length != 1) {
                System.err.println("Usage:  java ReverseTest 
string_to_reverse");
                System.exit(1);
            }
            String stringToReverse = URLEncoder.encode(args[0]);

            URL url = new 
URL("http://java.sun.com/cgi-bin/backwards");
            URLConnection connection = url.openConnection();

            PrintStream outStream = new 
PrintStream(connection.getOutputStream());
            outStream.println("string=" + stringToReverse);
            outStream.close();

            DataInputStream inStream = new 
DataInputStream(connection.getInputStream());
            String inputLine;

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {
            System.err.println("IOException: " + ioe);
        }
    }
}

このプログラムを考察し、動作の仕組みを見てみよう。まず、このプログラムはコマ ンドライン引数を処理している。

if (args.length != 1) {
    System.err.println("Usage:  java ReverseTest string_to_reverse");
    System.exit(1);
}
String stringToReverse = URLEncoder.encode(args[0]);

これらの行は、ユーザがプログラムに 1 つだけコマンドライン引数を指定している ことを確認し、引数をコード化している。このコマンドライン引数が、cgi-bin スク リプトの backwards によって逆にされる文字列である。 コマンドライン引数の中に、空白文字や英数字以外の文字があってもよいが、文字列 にはサーバへ到達するまでにさまざまな処理が行われるため、このような文字はコー ド化する必要がある。文字のコード化は URLEncoder クラスによって実現される。

このプログラムは次に、java.sun.com 上の backwards スクリプトの URL である、URL オブジェクトを作成する。

URL url = new URL("http://java.sun.com/cgi-bin/backwards");

その次に、URLConnection を作成し、そのコネクションで出力ストリームを開く。 出力ストリームは PrintStream を通してフィルタされる。

URLConnection connection = url.openConnection();
PrintStream outStream = new PrintStream(connection.getOutputStream());

上記の 2 番目の行は、コネクション上で getOutputStream() メソッ ドを呼び出している。URL が出力をサポートしていない場合は、このメソッドは UnknownServiceException をあげる。URL が出力をサポートしている場合は、このメ ソッドはサーバ側で URL の標準入力に接続されている出力ストリームを返す。クラ イアントの出力はサーバの入力である。

次にプログラムは、出力ストリームに必要な情報を書き込み、ストリームを閉じる。

outStream.println("string=" + stringToReverse);
outStream.close();

この行は println() メソッドを使用して、出力ストリームに書き込ん でいる。 このように、URL へデータを書き込むことは、ストリームへ書き込むのと同じように 簡単に行えるのである。 クライアント側の出力ストリームに書き込まれたデータは、サーバ側の backwards スクリプトの入力となる。ReverseTest プログラムは、 string= を、逆にされるコード化された文字列に連結することによっ て、スクリプトが求める書式で入力を構築している。

この例で見られるように、多くの場合、URL に書き込むということは、ユーザの書い た情報を読み取り、何らかの処理をした後、同じ URL を通して情報を戻す cgi-bin スクリプトに情報を渡すことなのである。したがって、URL に書き込んだ後はそこか ら情報を読み取るべき場合が多い。ReverseTest プログラムは次にそれを行っている 。

DataInputStream inStream = new 
DataInputStream(connection.getInputStream());
String inputLine;

while (null != (inputLine = inStream.readLine())) {
    System.out.println(inputLine);
}
inStream.close();

Reverse Me を引数として ReverseTest プログラムを実行すると、出 力は次のようになる。

Reverse Me
 reversed is:
eM esreveR


Previous | Next | Trail Map | Custom Networking and Security | URL を扱う