ついにベールを脱いだJavaFX

第11回 通信と非同期処理

この記事を読むのに必要な時間:およそ 12 分

HttpRequestクラスを使用した通信

javafx.io.http.HttpRequestクラスはクラス名からもわかるように,HTTPに特化したクラスです。このため,HTTPの細かな制御を行うことも可能です。たとえば,RemoteTextDocumentクラスではGETかPOSTしか使用することができませんでしたが,HttpRequestクラスではPUTやDELETEも扱うことができます。

では,まず先ほどと同じようにリモートにあるドキュメントをHttpRequestクラスを使って取得してみましょう。

リスト2

ar charset: String;
var request: HttpRequest;
 
request = HttpRequest {
    location: "http://gihyo.jp/dev/serial/01/javafx"
 
    onResponseHeaders: function(headerNames: String[]) {
        for (headerName in headerNames) {
            if (headerName == "content-type") {
                // HTTPヘッダの content-type から文字コードを取得
                var contentType
                    = request.getResponseHeaderValue(headerName);
                var index = contentType.indexOf("=");
                charset = contentType.substring(index+1);
            }
        }
    }
 
    onInput: function(stream: InputStream) {
        var reader: BufferedReader;

        if (charset != null) {
            // 文字セットを指定してリーダを生成
            reader = new BufferedReader(
                new InputStreamReader(stream, charset));
        } else {
            reader = new BufferedReader(
                new InputStreamReader(stream));
        }
            
        while(true) {
            var text = reader.readLine();
            if (text == null) {
                break;
            }
            println(text);
        }
        
        stream.close();
    }
}
 
// リクエストをキューに入れる 
request.enqueue();
 
Stage {
    title: "Dummy"
    scene: Scene {
        width: 200
        height: 200
        content: [  ]
    }
}

RemoteTextDocumentクラスを使ったサンプルよりもずいぶん長くなってしまいました。

HttpRequestクラスでは接続するサーバのURLはlocationアトリビュートで設定します。ここでは,先ほどと同じく本連載のインデックスページに設定しました。

HttpRequestクラスではonXというアトリビュートが多く定義されています。X の部分にはConnectingやReadingなどHTTPの状態を表した言葉が入ります。これらのアトリビュートには,個々の状態の時にコールされるコールバック関数を設定することができます。

上記のスクリプトでは,レスポンスのヘッダを読み込んだ後にコールされるonResponseHeadersアトリビュートと,レスポンスのボディを読み込める状態になったときにコールされるonInputアトリビュートを設定しています。

onResponseHeadersアトリビュートでは引数としてヘッダの名前の一覧が与えられます。もし,ここで文字セットを表すcontent-typeがあれば,ヘッダ名から値を取得するgetResponseHeaderValue関数を使用して値を取得します。content-typeは"text/html; charset=UTF-8"のように表されるので,charset=の後の部分を取り出して,charset変数に代入しておきます。

次にonInputアトリビュートでボディの読み込みを行います。onInputアトリビュートでは引数としてInputStreamオブジェクトが与えられます。そこで,先ほど設定したcharsetを使用してリーダを生成させます。

後は,生成したリーダを使用して読み込みを行います。

なお,HttpRequestクラスはオブジェクトを生成するだけでは,通信を行いません。通信を行うのは,青字で示したenqueue関数をコールした後です。

では,実行してみましょう。図2に実行結果を示しました。

図2 HttpRequestクラスサンプルの実行結果

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>連載:ついにベールを脱いだJavaFX|gihyo.jp … 技術評論社</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <<以下,省略>>

RemoteTextDocumentクラスを使った場合と異なり,文字化けを起こすことなく読み込みが行えました。

著者プロフィール

櫻庭祐一(さくらばゆういち)

横河電機に勤務するかたわらJava in the Boxにて新しい技術を追い続けています。JavaOneは今年で11年目。名実共にJavaOneフリークと化しています。