2011年2月21日月曜日

Struts 2の仕組みと構造

Struts 2アプリケーションの構造

Struts 2アプリケーションの構造

 では、Struts 2アプリケーションの構造を見てみましょう。

Controller

 コントローラ部がStruts 2のコア部分であり、FilterDispatchがすべての制御を担っています。intercetors(インターセプタ)とは実際の処理を実装したコンポーネントで、HTTPリクエストの処理や、結果の後処理、例外処理など、Struts 2で複数提供されています。

Model

 モデル部は、前述のActionクラスとなっていて、アプリケーションで用意するクラスです。リクエストURIに対応する形になり、Struts 2側でリクエストごとにオブジェクトの生成が行われます。Struts 1では、このあたりの構造がゴチャゴチャしていましたが、Struts 2ではロジックとデータがActionクラスにまとまり、すっきりしたオブジェクト指向的な設計になっています。

View

 ビューでは、URIリクエストの結果ページを表示します。デフォルトでは、HTMLテンプレートとしてJSPが利用されます。その他、FreeMarkerVelocityといったテンプレートも使えます。Struts 2が提供するカスタムタグを用いて、Actionクラスのデータにアクセスすることになります。

 Struts 2アプリケーションの構成

WEB-INF/libにおくべきJarファイル

struts-2.0.11-all.zipを解凍してできたlibディレクトリ以下のファイルが、Struts 2本体とプラグインファイルです。その中で基本となるのは次の5ファイルです。

§           commons-logging-1.0.4.jar

§           freemarker-2.3.8.jar

§           ognl-2.6.11.jar

§           struts2-core-2.0.11.jar

§           xwork-2.0.4.jar

 これらのJARファイルをドラッグ&ドロップして、WEB-INF/libにコピーしておきます。

web.xml

 次に、デプロイメント・ディスクリプタ(web.xml)を作成しましょう。web.xmlは、Webアプリケーションの設定を記述するファイルで、WEB-INFフォルダの直下に置きます。web.xmの中身は、次のようになります。

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://

                     java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher

        </filter-class>

    </filter>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

 

    <welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

 

</web-app>

 <filter>で、FilterDispatcherクラスからなるstruts2というフィルタを定義しています。<filter-mapping>は、フィルタを呼び出すURIパターンの関連付けで、ここではすべてのリクエストがstruts2フィルタを通る設定になっています。このフィルタの設定は、基本的には、アプリケーションごとに変更する必要はありません。Struts 1では、ここで直接サーブレットを指定していましたが、struts 2では、Java Servlet API 2.3で取り入れられたフィルタを利用する設定となっています。FilterDispatcherというフィルタクラスがすべてのリクエストを受けて、処理を割り振るようになっているのです。<welcome-file-list>とは、いわゆるウェルカムページの指定で、ApacheでのDirectoryIndexと同様です。

 ここでのポイントは、Struts 2では、FilterDispatcherクラスがフィルタとしてすべてのリクエストを処理しているということです。すなわち、前述のMVCパターンでのC、コントローラにあたります。

index.jsp

 index.jspファイルの中身は次のようにします。

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC

 "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Hello!Project</title>

</head>

<body>

<a href="Hello.action">こんにちは</a>

<br />

<s:property value="replyMsg"/>

</body>

</html>

 

 ここで1つのポイントは、カスタムタグです。

<%@ taglib prefix="s" uri="/struts-tags" %>

 を宣言すると、Struts 2で提供されている独自のタグが使えるようになります。

Actionクラス

 Hello.actionの正体は、名前が示すようにActionクラスの実行です。拡張子の「.action」によって、Struts 2はリクエストがActionであることを認識します。この設定は、後述する設定ファイルにて変更可能ですので、Struts 1のように「.do」とすることもできます。

 Hello.actionが実行されると、それに対応したActionクラスがStruts 2を通して呼び出されます。Actionクラスは前述のとおりアプリケーションのビジネスロジックを実装するクラスです。

Hello.java

package sample1;

 

public class Hello {

 

    private String replyMsg;

 

    public String getReplyMsg() {

        return replyMsg;

    }

 

    public void setReplyMsg(String message) {

        this.replyMsg = message;

    }

 

    public String execute() throws Exception {

        this.setReplyMsg( "Struts 2の世界へようこそ" );

        return "success";

    }

}

 Helloクラスは、replyMsgというString型のメンバ変数と、その変数を設定・取得するセッターとゲッター、そしてexecute()というString型を返すメソッド、という構成です。これはすべてのActionクラスの基本構成となります。実はこれ、Struts 2のライブラリで用意されているActionインターフェースの実装とも言えるのですが、前述のようにActionクラスは、インターフェースをインプリメントせずに(Javaの文法的な意味で)、POJOとして作成可能となっています。

 execute()メソッドでは、replyMsgに文字列を設定しています。つまり、Hello.actionが実行されると、このメソッドがStruts 2によって呼び出されるということです。デフォルトでは、executeという名前のメソッドを呼び出すことになっています。後述する設定ファイルで、String型を返す別のメソッドを指定することもできます。また、先ほどのプロパティとは、このActionクラスのreplyMsgを参照していることが分かると思います。ただし、メンバ変数を直接参照できないので、いわゆるゲッターが必要です。Struts 2が、value="replyMsg"で指定された値にgetをつけたメソッドを実行しているのです。

struts.xml

 最後のファイル、struts.xmlは、アプリケーションの動作を定義しています。ここでは、リクエストURIActionクラスの対応や、ページ遷移の設定を記述しており、Struts 2アプリケーションでは重要な設定ファイルとなっています。なお、このファイルは、実際にはクラスパスの直下に配置することになるのですが(つまり、「/WEB-INF/classes」フォルダ)、今回の開発環境では、/WEB-INF/src/struts.xmlに作成します。

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC

        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

    <package name="HelloProject" extends="struts-default">

 

        <action name="Hello" class="sample1.Hello">

            <result name="success">/index.jsp</result>

        </action>

 

    </package>

</struts>

 これが最低限の設定になっています。<struts>タグがトップレベルの要素で、その配下の<package>タグ内にActionクラスの設定を定義していきます。packageといっても、Javaソースのパッケージとは関係なく、あくまでもStruts 2の設定で、複数のActionをグルーピングして管理できるようようにするものです。extends="struts-default"は、このpackageがデフォルトの設定ファイルを継承して標準の処理を行うという意味で、通常は変更する必要はありません。

 <action>タグでは、name属性でリクエストURIclass属性で対応するActionクラスを定義します。また、method属性を設定すると、execute以外の指定したメソッドを呼び出すこともできます。

 <result>タグは、Actionクラスの実行の次の処理を定義しています。name属性で、呼び出したActionクラスのメソッドの返値を指定します。今回の例では、戻り値が"success"の場合、index.jspを実行するという設定になっています。戻り値によって異なるページを表示したい場合は、<result>タグを複数並べることになります。なお、name属性のデフォルトは"success"なので、name属性の設定を省略すると、"success"を設定したことになります。

 ちなみに、Actionの拡張子は、以下のタグを<struts>要素内に記述することで変更可能で、例えばStruts 1と同じ拡張子にするには以下の設定になります。位置は<package>要素の前後どちらでもかまいせん。

Actionの拡張子を変更する

<constant name="struts.action.extension" value="do" />

 

0 件のコメント:

コメントを投稿