連載
» 2008年10月06日 00時00分 公開

オープンソースTERASOLUNAで作るWebアプリ(1):Strutsの諸問題を解決するWebフレームワークとは? (1/3)

[師芳卓,株式会社NTTデータ]

 本連載では、4回にわたってWebフレームワークの1つとしてオープンソース化された「TERASOLUNA Server Framework for Java」(以下、TERASOLUNAフレームワーク)を紹介します。

 TERASOLUNAフレームワークが、いかにしてWebアプリケーションに特有のセッション管理認証処理トランザクション管理などの煩雑な処理を簡素化し、業務開発者が業務処理の実装に集中できる仕組みを提供しているかについて説明します。

編集部注:「TERASOLUNA Server Framework for Java」を含むTERASOLUNA全体について詳しく知りたい読者は、特集「Java、.NET、Ajax開発の“銀の弾丸”オープンソース?」をご覧ください。

いま、そこにあるStrutsの諸問題

 Strutsは、オープンソースのWebフレームワークとしてApache Software Foundationにより開発され、公開から8年が経つ2008年現在でも、Webシステムの標準的フレームワークとして使われ続けています。

図1 StrutsのTOPページ 図1 StrutsのTOPページ

 しかしStrutsは、Webブラウザを介したアプリケーション開発に必要な基本的な機能を備えているものの、「モジュールの独立性」「プログラムの可読性」「テスト容易性」といったところになると、各プロジェクトの業務開発者の技量に任されるところが多くなります。

“アクション”を実装する危険性

 例えば、オンライン系のシステム開発に不慣れな業務開発者がプレゼンテーション層の煩雑な処理に苦戦する姿をしばしば見掛けることがあります。

 Strutsのみを使用したWebアプリケーションの場合、StrutsのActionクラスの継承クラスにてリクエストセッション変数属性値)の入出力処理を実装し、業務ロジックの呼び出しを行うのが一般的です。

 しかし、システム開発において、“アクション”を業務開発者が直接実装することには、開発者間での意識の違いによる手戻りやシステムダウンのリスクなどを発生させる要因にもなり得ます。

複雑なセッション管理

 またStrutsを使った開発では、セッションへの変数(属性値)の登録、削除処理を業務開発者が直接コーディングする場合、非常に厳密に削除処理を実装する必要があります。

 変数を複数リクエスト間で保持しておくためには、「セッション」と呼ばれる複数リクエストにまたがる通信を開始し、セッション用としてサーバ側に確保したメモリ空間に変数を格納しなければなりません。しかし、セッションに保存された変数は、基本的にはログアウト、もしくはタイムアウトでセッションが切れるまで残り続けます。そのため、「消す処理を記述する」という業務開発者にとって負担の大きい作業が発生する問題があります。

 セッションに保存された変数の消し忘れが生じたときは、メモリ領域が圧迫されます。最悪の場合「OutOfMemoryErrorによりシステムがダウンする」といった事態を引き起こすことになります。

図2 プロジェクトでの業務開発者の作業(Strutsのみの場合) 図2 プロジェクトでの業務開発者の作業(Strutsのみの場合)

変数管理も開発者の大きな負担の1つ

 また、業務処理で使用する変数(属性値)の管理も開発者の大きな負担の1つです。検索結果の一覧表示、情報の入力、登録処理となると、使用する変数の個数が数十になることは珍しいことではありません。

 その際に業務開発者は、「どのオブジェクト(アクションフォーム、リクエスト、セッション……)からどのフィールドの値を取得し、処理した結果をどのオブジェクトのどのフィールドに反映しなくてはならないのか」を逐一整理しつつ、処理を記述しなければなりません。そして、その情報は複数リクエスト間で整合性が取れてなければなりません。

 そのため、一業務の連続する画面遷移についてリクエスト処理を分業化するためには、変数の管理情報を業務開発者間で共有する必要があり、開発の効率性を妨げる1つの要因となっています。

リスト1 Strutsのみを用いたアプリケーションでのActionクラスの実装例
package xxxx.project.action;
//importは省略

public class SampleAction extends Action {

    // 属性のキーXXXX_KEYをfinal static Stringで宣言(省略)【1】

    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
    throws Exception {

        HttpSession session = request.getSession();

        //セッションから入力データを取得【2】
        String firstName = (String)session.getAttribute(
            FIRST_NAME_KEY);
        String lastName = (String)session.getAttribute(
            LAST_NAME_KEY);

        //業務処理の開始【3】
        SampleBLogic blogic = new SampleBLogic();
        String welcomeMessage = blogic.generateWelcomeMessage(
            firstName, lastName);
        
        //結果をリクエストオブジェクトに格納
        request.setAttribute(WELCOME_MESSAGE_KEY, welcomeMessage );

        return mapping.findForward("success");
    }
}

【1】属性のキーは別アクションと一致させる必要がある
【2】セッション管理を業務プログラマーが行うため削除漏れ、キー設定ミスなどが生じやすい
【3】業務処理の呼び出しを業務プログラマーが書く必要がある

 また、変数名などの仕様変更のたびに、各業務処理に記述されたキーとなる文字列を修正する作業が発生するため、「仕様変更への柔軟性も低い」といえます。

アクションと業務ロジックの高い依存性

 “アクション”継承クラスでの業務ロジックの呼び出し処理の記述も、業務開発者の大きな負担となっています。業務ロジックはPOJO(Plain Old Java Object)であるため、メソッド形式は業務開発者が自由に決めることができます。

 その一方で、呼び出し側ではメソッドに合わせて、必要な入力オブジェクトを生成し、返却された出力オブジェクトの値をセッションなどに反映させる処理を記述しなければなりません。このような呼び出し前後の処理は、機械的な作業である割に量が多く業務開発者に余計な負担を増やしています。

業務開発者は本質的な処理に集中したい!

 そもそも、業務開発者は、「ユーザーからの登録情報を基にDB更新のクエリを発行する」「ユーザーから送られた検索条件データを基にDBに検索クエリを投げ、結果を返却する」などの本質的な処理に集中するべきなのに、なぜ、リクエスト間の変数の管理やトランザクション処理などの本質的でない処理を書かなければならないのでしょうか?

 次ページ以降で紹介するTERASOLUNAフレームワークは、これらの煩雑な処理を一手に引き受けるための仕組みを、さまざまなフレームワークとの連携と、独自の仕様拡張によって実現しています。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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