連載
» 2008年07月25日 00時00分 公開

業務用RIAの本命!? Flex+Java開発入門(3):StrutsやRESTなWebサービスとFlexを連携するには? (3/4)

[福田寅成,クラスメソッド株式会社]

HTTPServiceによるサーバへのリクエスト処理

 それでは、Struts 1系の処理を呼び出す部分を見ていきましょう。この処理はHTTPServiceによるサーバアクセス処理の基本になっています。

    // HTTPService基本設定
    view.srvStruts1Quiz.url = AppConsts.SERVER_URL_STRUTS1_QUIZ;
    view.srvStruts1Quiz.method = URLRequestMethod.POST;
    view.srvStruts1Quiz.addEventListener(ResultEvent.RESULT,     onGetQuizListStruts1_result);
    view.srvStruts1Quiz.addEventListener(FaultEvent.FAULT,     onGetQuizListStruts1_fault);
    
    // HTTPServiceリクエストパラメータ設定
    // 特にパラメータは設定していません
    var variables:URLVariables = new URLVariables();
    
    view.srvStruts1Quiz.request = variables;
    
    // リクエストの実行(トークンを保持しておく)
    var at:AsyncToken = view.srvStruts1Quiz.send();

HTTPServiceの基本的な設定

 最初に、HTTPServiceの基本的な設定を行います。最初にクイズの設問を取得しにいくので、srvStruts1Quizオブジェクトを利用します。

 まずは、サーバ処理を呼び出すurlを指定しています。定数で指定していますが、実際の値は「http://localhost:8400/AtmarkitQuizAppStruts1/quiz/QuizAction.do」です。[Ctrl]キー+クリックで実際のソースで確認してみてください。最後の「.do」がまさにStrutsサンプルといわんばかりのURLになっています。

 次に、methodを指定しています。ここでは、「POST」を指定しています。HTMLのフォームで指定するメソッドでおなじみですね。HTTPのメソッド種別の指定になります。詳細はヘルプでURLRequestMethodクラスを参照してください。

 最後に、サーバリクエスト処理の「結果イベント」「失敗イベント」に対するハンドラを指定しています。HTTPServiceでリクエスト処理(後述のsend)を呼び出すと、その後2つのイベントが発生する可能性があります。そのイベントタイプが「ResultEvent.RESULT」「FaultEvent.FAULT」の2つです。それぞれは単なる文字列です。

 ResultEventイベントはサーバから正常なレスポンスが返ってきた際に発生するイベントでそのイベントハンドラ内でサーバからのレスポンスを取得します。FaultEventイベントはサーバからのレスポンスが正常でなかった場合(I/Oエラー(エラーコード「404」)やサーバエラー(エラーコード「500」)など)に発生するイベントで、その中でクライアントにエラーの旨を表示したりする処理を記述します。

 このイベントとイベントハンドラのHTTPServiceオブジェクトへの関連付けを「addEventListerner」メソッドによって行っています。このaddEventListenerメソッドは各コンポーネントの用意されているイベントに対して、イベントの種別とそのイベントが発生した際のハンドラを指定するFlexで最も重要なメソッドのうちの1つです。メソッドの呼び出し方はどのような場合でも同じです(ただし、メソッドには3番目以降の任意指定の引数があります)。

 今回のクイズ設問取得処理に関しては、以下の2つが呼ばれます。

  • 成功イベントでは、onGetQuizListStruts1_result
  • 失敗イベントでは、onGetQuizListStruts1_fault

 それぞれ下記のルールでハンドラ名を付けています。

on + メソッド名 + _(アンダーバー) + イベント種類

リクエストパラメータの設定

 次に、URLVariablesオブジェクトによるリクエストパラメータの設定ですが、今回この処理は不要なので何も設定していません。

 例えば、ユーザーネームを送りたい場合は、以下のようにURLVariablesオブジェクトに直接送りたいパラメータを指定し、値をセットします。

    variables.userName = "福田寅成"

サーバを呼び出す

 最後に、sendメソッドを実行してサーバを呼び出します。AsyncTokenの解説は省略します。

E4X形式によるサーバからのレスポンス処理

 サーバ側の処理解説の前に、引き続きサーバ結果処理のハンドラの処理を見ていきましょう。onGetQuizListStruts1_resultメソッドは非常に簡単な処理になっています。

    // レスポンスのXMLをQuizオブジェクトのリストに変換
    createQuizListFromXML(XML(event.result));
    
    // 引き続き、コメントをサーバから取得する
    getCommentListStruts1();

 最初の処理でサーバからのレスポンス(XML(E4X)形式)をActionScriptで扱いやすいオブジェクト形式に変換しています。その後、コメントをサーバに取得に行っています。

注意! 【Flex試験に出るくらい、重要】

上記のeventはResultEventです。このResultEventの「result」プロパティにサーバからのレスポンスが格納されています。逆に、HTTPServiceオブジェクト(ここではsrvStruts1Quiz)の「lastResult」プロパティにも同じサーバからのレスポンスが格納されています。

この2つの違いは、Flex開発者試験に出ますので覚えておきましょう! また、試験を受験しない方も覚えておきましょう!


設問のデータを確認

 最初の、サーバからのレスポンスを解析する処理(createQuizListFromXML)を詳しく見ていきましょう。先に、サーバから送られてくるXMLを確認しておきます。

<quizList>
    <quiz>
        <question>DTOとは何の略か</question>
        <selectors/>
        <correct>Data Transfer Object</correct>
    </quiz>
    
……(省略、quizが全部で10ペア)……
    
    </quiz>
</quizList>
設問データXML

E4X形式の具体的な効果

 このXMLがevent.resultに格納されています。これをcreateQuizListFromXMLで解析していきます。

    /** 
    * XMLクイズデータのオブジェクト化
    * 
    * @param xml XML
    */
    private function createQuizListFromXML(xml:XML):void {
        quizList = new Array();
        var quizXML:XML;
        var quiz:Quiz;
    
        for each (quizXML in xml.quiz) {
            trace(quizXML);
            quiz = Quiz.populate(quizXML)
            quizList.push(quiz);
        }
    }

 特徴的なのは、for文と「Quiz.populate」の部分です。for文はXMLをE4Xで解析する場合の典型的な処理の1つです。サンプルのfor文のように書くと、quizXMLに<quiz>タグが1件1件ループごとに入ってきます。その<quiz>タグの指定はinの右辺の「xml.quiz」で指定されています。

 この「xml.quiz」のドット「.」もE4Xの特徴です。直感的に分かるように、このドットはXMLの子を取得する処理です。従来、XML処理に関しては非常に面倒な処理を記述する必要がありましたが、E4Xによりかなり処理が簡潔で直感的なものになっていることが分かると思います(このように、XMLからオブジェクトに変換しなくても、取得したXMLのままで適宜E4Xを用いながら処理を続行していくことも可能です。このような変換処理は必須ではありません)。

筆者が作成したユーティリティメソッド

 次に「Quiz.populate」ですが、これは筆者が作成したユーティリティメソッドです。単純に1件のXMLを1件のQuizオブジェクトに変換しています。実際にメソッドの中身を確認してみましょう。

    public static function populate(xml:XML):Quiz {
        var quiz:Quiz = new Quiz();
    
        if(xml.question) {
            quiz.question = String(xml.question).replace(省略); 
        }
        if(xml.selectors) {
            quiz.selectors = xml.selectors; 
        }
        if(xml.correct) {
            quiz.correct = xml.correct; 
        }
        return quiz;
    }

 中身は非常に簡単な処理です。各XMLから要素が存在していたら、その要素を新規作成したQuizオブジェクトに設定しています。if文の条件文は慣れない方が多いと思いますが、ActionScriptでは、このような存在チェックを掛けることも可能です。

クイズパネルを初期化

 以上で、クイズの設問リストが取得できました。コメント取得処理に関しては省略しますが、コメント取得処理の結果処理を見ておきますと、onGetCommentListStruts1_resultにサーバからのコメントデータの変換処理後に、initPanelメソッドでクイズパネルを初期化している処理があります。

 次ページのサーバ側処理の解説の後のクイズ画面表示処理で、このinitPanelメソッドの解説を行います。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。