URL を扱う |
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 へ書き込めるようにしておくだけで、データがサーバに送られる。 プログラムでは以下のステップによってこの機能を実現できる。
- URL を作成する。
- URL へのコネクションを開く。
- コネクションから出力ストリームを得る。 この出力ストリームはサーバ上の cgi-bin スクリプトの標準入力に接続している。
- 出力ストリームに書き込む。
- 出力ストリームを閉じる。
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
URL を扱う |