Seasar DI Container with AOP

S2Struts概要

S2Strutsを使うと、S2とStrutsが簡単に連動するようになります。 Actionクラスにサービスコンポーネントが自動的に設定されるので、 Actionクラスの役割は適切なサービスコンポーネントを呼び出すだけになります。 Actionクラスはコントローラに徹することで、プレゼンテーション層とサービス層の役割分担も明確になります。 また、Actionに対してAOPを適用することもできます。

セットアップ

S2と同様にJDK1.4 or JDK1.5が必要です。稼動確認は、Eclipse3.1で行っています。

S2StrutsVx.x.x.zipを解凍してできたs2strutsディレクトリをEclipseのJavaプロジェクトとして丸ごとインポートしてください。 .classpathを上書きするか聞かれるので、全て、はいのボタンをクリックして、全てを取り込みます。 これで、私と全く同じ開発環境になります。

サンプルは、 TomcatTomcat Pluginを使うことを前提にしています。 あらかじめインストールしてください。

サンプルはS2StrutsExampleVx.x.x.zipとして別途用意されているので、 ダウンロードして解凍してください。Eclipseでs2struts-exampleという名前でJavaプロジェクトを作成します。 Tomcatプロジェクトではないので気をつけてください。解凍してできたs2struts-exampleディレクトリを丸ごとインポートしてください。 .classpathを上書きするか聞かれるので、全て、はいのボタンをクリックして、全てを取り込みます。 s2struts-exampleプロジェクトを右クリックしてプロパティ->Tomcatを選びます。Tomcatプロジェクトであるをチェックし、 アプリケーションURIを/s2struts-exampleとします。これで、Tomcatを再起動して、 ブラウザからhttp://localhost:8080/s2struts-example/にアクセスすると S2Strutsを使用したサンプルを見ることができます。 ただし、Employee Managementサンプルを見る場合は、WEB-INF/binにあるrunHsqldb.batでHSQLDBを起動させておいてください。

S2StrutsBlankVx.x.x.zipには、S2Strutsを利用するために必要なファイルがすべて含まれています。 さらにMayaa、S2Dao等のWebアプリケーション開発に便利なファイルも含まれています。 開発するWebアプリケーションの雛型として利用する場合、以下のファイル一覧を参照し利用しないファイルを削除してください。

・S2Strutsを利用するために必要なファイルです。
WEB-INF/
        struts-config.xml             
        tiles-defs.xml                
        validation.xml                
        validator-rules.xml           
        web.xml                       

WEB-INF/lib
        javassist-3.0.jar                 
        commons-logging-1.0.4.jar           
        log4j-1.2.8.jar               
        ognl-2.6.5.jar                
        aopalliance-1.0.jar               
        s2-framework-2.x.x.jar        
        
        commons-beanutils-1.7.0.jar         
        commons-digester-1.6.jar          
        commons-fileupload-1.0.jar        
        commons-validator-1.0.4.jar         
        oro-2.0.8.jar               
        struts-1.2.8.jar                    
        
        s2-struts-x.x.x.jar           

WEB-INF/src
        log4j.properties              
        application.properties        
        app.dicon                     
        s2struts.dicon                


・S2拡張機能を利用するために追加したファイルです。
WEB-INF/lib
        jta.jar                       
        junit-3.8.1.jar               
        poi-2.5-final-20040804.jar    
        s2-extension-2.x.x.jar

WEB-INF/src
        j2ee.dicon                    
        aop.dicon                     


・Mayaaを利用するために追加したファイルです。利用しない場合は削除してください。
WEB-INF/lib
        jaxen-1.1-beta-8.jar          
        nekohtml-0.9.5.jar            
        rhino-1.6r2.jar               
        xercesImpl-2.7.1.jar          
        xml-apis-1.3.jar              
        mayaa-x.x.x.jar                


・S2Daoを利用するために追加したファイルです。利用しない場合は削除してください。
WEB-INF/lib
        s2-dao-x.x.x.jar              

WEB-INF/src
        dao.dicon                     


・HSQLDBを利用するために追加したファイルです。利用しない場合は削除してください。
WEB-INF/lib
        hsqldb.jar                    

Tigerアノテーションを使いたい場合は、S2StrutsTigerVx.x.x.zipを解凍してできたs2struts-tigerディレクトリの

  • lib/s2-struts-tiger-x.x.x.jar

をWEB-INF/libにコピーし、CLASSPATHに含めてください。

backport175アノテーションを使いたい場合は、S2StrutsBackport175Vx.x.x.zipを解凍してできたs2struts-backport175ディレクトリの

  • lib/s2-struts-backport175-x.x.x.jar
  • lib/backport175-1.0.jar

をWEB-INF/libにコピーし、CLASSPATHに含めてください。

クイックスタート

早速試してみましょう。

クイックスタートは、 TomcatTomcat Pluginを使うことを前提にしています。 あらかじめインストールしてください。

S2Strutsを簡単に利用するためにS2StrutsBlankVx.x.x.zipを使います。 S2StrutsBlankVx.x.x.zipを解凍してs2struts-blankディレクトリをEclipseのJavaプロジェクトとして丸ごとインポートしてください。 .classpathを上書きするか聞かれるので、全て、はいのボタンをクリックして、全てを取り込みます。 s2struts-blankプロジェクトを右クリックしてプロパティ->Tomcatを選びます。これで準備はできました。

まずはデモ画面となるHTMLから作成します。s2struts-blank直下にgreetingInput.html、greeting.htmlを作ります。

greetingInput.html

時間帯を指定する画面です。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
  <title>Greeting Demo</title>
</head>
<body>
  <form method="GET" action="greeting.html">
    <table>
      <tr>
        <th>time</th>
        <td>
          <select name="time">
            <option value="" selected>Please select</option>
            <option value="a.m.">a.m.</option>
            <option value="p.m.">p.m.</option>
          </select>
        </td>
      </tr>
    </table>
    <input type="submit" value="greeting">
  </form>
</body>
</html>

greeting.html

時間帯ごとのあいさつを表示する画面です。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
  <title>Greeting Demo</title>
</head>
<body>
  <table>
    <tr>
      <th>time</th>
      <td>a.m.</td>
    </tr>
    <tr>
      <th>greeting</th>
      <td>Good morning</td>
    </tr>
  </table>
  <a href="greetingInput.html">back</a>
</body>
</html>

ブラウザでgreetingInput.htmlを表示すれば、これから作成するアプリケーションの紙芝居をみることができます。

作るもののイメージがわきましたか?

それでは実際に動くものにしていきます。作業手順は次のようになります。

  • インターフェースを作る
  • インターフェースを実装し部品を作る
  • それぞれの部品をつなげる

今回はActionをPOJOで作り、ビューにはMayaaを利用します。 S2StrutsではActionをPOJOとする場合、インターフェースと実装をわける必要があります。 詳しくは「ActionをPOJOにした使い方」を参照してください。

最初にGreetingInputInitAction、GreetingAction、GreetingServiceインターフェースを作ります。 画面とのインターフェースという意味でActionForm(DTO)となるGreetingDtoも作ります。

GreetingDto

POJOのDTOをActionFormとして利用します。画面からわたってくる項目を持たせます。

package examples.dto;

public class GreetingDto {
    private String time = "";

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

GreetingInputInitAction

greetingInput.htmlを表示するために必要となる情報を提供するActionインターフェースです。

package examples.action;

public interface GreetingInputInitAction {
    String initialize();
}

GreetingAction

あいさつ処理を行うActionインターフェースです。

package examples.action;

public interface GreetingAction {
    String SUCCESS = "success";
    
    String goGreeting();
}

GreetingService

Strutsなどのプレゼンテーション層フレームワークに依存しないサービスを提供するインターフェースです。

package examples.service;

import java.util.List;
import examples.dto.GreetingDto;

public interface GreetingService {
    List getTimeList();

    String getGreeting(GreetingDto dto);
}

これで一通りインターフェースを作ることができました。次はインターフェースを実装し部品を作ります。

GreetingInputInitActionImpl

setGreetingServiceはGreetingServiceをインジェクションするためのセッターメソッドです。 getTimeListは画面へ情報を渡すためのゲッターメソッドです。

package examples.action.impl;

import java.util.List;
import examples.action.GreetingInputInitAction;
import examples.service.GreetingService;

public class GreetingInputInitActionImpl implements GreetingInputInitAction {
    private GreetingService service;
    private List timeList;

    public String initialize() {
        timeList = service.getTimeList();
        return null;
    }
    
    public void setGreetingService(GreetingService service) {
        this.service = service;
    }

    public List getTimeList() {
        return timeList;
    }
}

GreetingActionImpl

setGreetingServiceはGreetingServiceをインジェクションするためのセッターメソッドです。 setGreetingDtoはActionFormを画面から受け取るためのセッターメソッドで、getGreetingDtoはActionFormを画面へ渡すためのゲッターメソッドです。 getGreetingは画面へ情報を渡すためのゲッターメソッドです。

package examples.action.impl;

import examples.action.GreetingAction;
import examples.dto.GreetingDto;
import examples.service.GreetingService;

public class GreetingActionImpl implements GreetingAction {
    private GreetingService service;
    private GreetingDto greetingDto;
    private String greeting;

    public String goGreeting() {
        greeting = service.getGreeting(greetingDto);
        return SUCCESS;
    }

    public void setGreetingService(GreetingService service) {
        this.service = service;
    }

    public GreetingDto getGreetingDto() {
        return greetingDto;
    }

    public void setGreetingDto(GreetingDto greetingDto) {
        this.greetingDto = greetingDto;
    }

    public String getGreeting() {
        return greeting;
    }
}

GreetingServiceImpl

package examples.service.impl;

import java.util.ArrayList;
import java.util.List;
import examples.dto.GreetingDto;
import examples.service.GreetingService;

public class GreetingServiceImpl implements GreetingService {
    private static final String AM = "a.m.";
    private static final String PM = "p.m.";

    public List getTimeList() {
        List result = new ArrayList();
        result.add(AM);
        result.add(PM);
        return result;
    }

    public String getGreeting(GreetingDto dto) {
        if (AM.equals(dto.getTime())) {
            return "Good morning";
        }
        if (PM.equals(dto.getTime())) {
            return "Good evening";
        }
        return "";
    }
}

これですべての実装が終了し部品がそろいました。次はそれぞれの部品をつなげる作業をします。

greeting.dicon

ActionとServiceをつなげるためにgreeting.diconをexamples/diconの直下に作ります。

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
  "http://www.seasar.org/dtd/components21.dtd">
<components>
  <include path="aop.dicon"/>

  <component name="actionInterceptorChain"
      class="org.seasar.framework.aop.interceptors.InterceptorChain">
    <initMethod name="add"><arg>aop.traceInterceptor</arg></initMethod>
  </component>

  <component
    class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"examples.service.impl"</arg>
      <arg>".*ServiceImpl"</arg>
    </initMethod>
  </component>
  
  <component
    class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="instanceDef">
      @org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
    </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"examples.action.impl"</arg>
      <arg>".*ActionImpl"</arg>
    </initMethod>
  </component>
  <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
    <property name="interceptor">actionInterceptorChain</property>
    <initMethod name="addClassPattern">
      <arg>"examples.action.impl"</arg>
      <arg>".*ActionImpl"</arg>
    </initMethod>
  </component>

</components>

app.diconにincludeを追加してgreeting.diconを読み込むようにします。

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
  "http://www.seasar.org/dtd/components21.dtd">
<components>
  <include path="s2struts.dicon"/>
  <include path="examples/dicon/greeting.dicon"/>
</components>

今後、新しいActionを追加してもgreeting.diconを変更する必要はありません。これはS2が提供するコンポーネントの自動登録を利用しているからです。

最後の作業として、画面とAction、ActionFormをつなげるためにgreetingInput.html、greeting.htmlを修正し、対応するmayaaファイルを作ります。 Mayaaについての詳細は「JavaServer Templates "Mayaa"」を参照してください。

greetingInput.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
  <title>Greeting Demo</title>
</head>
<body>
<div id="appBody">
  <form method="GET" action="greeting.html" id="appForm">
    <table>
      <tr>
        <th>time</th>
        <td>
          <select name="time" id="time">
            <option value="" selected>Please select</option>
            <option value="a.m.">a.m.</option>
            <option value="p.m.">p.m.</option>
          </select>
        </td>
      </tr>
    </table>
    <input type="submit" value="greeting" id="goGreeting">
  </form>
</div>
</body>
</html>

greetingInput.mayaa

S2Strutsが用意しているinitタグを使用してGreetingInputInitAction#initialize()を呼び出します。 initialize()を実行することにより、画面の表示に必要なtimeListを取得します。

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org"
        xmlns:html="http://struts.apache.org/tags-html"
        xmlns:bean="http://struts.apache.org/tags-bean"
        xmlns:s2struts="http://www.seasar.org/tags-s2struts"
        m:noCache="true">

    <m:with id="appBody" replace="false">
        <s2struts:init action="#{greetingInputInitAction.initialize}"/>
        <m:doBody />
    </m:with>

    <html:form m:id="appForm" action="/greeting" method="POST" />
    <html:select m:id="time" property="time">
        <html:option value="">Please select</html:option>
        <html:options name="timeList" />
    </html:select>
    <html:submit m:id="goGreeting" >greeting</html:submit>

</m:mayaa>

greeting.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
  <title>Greeting Demo</title>
</head>
<body>
<div id="appBody">
  <table>
    <tr>
      <th>time</th>
      <td><span id="time">a.m.</span></td>
    </tr>
    <tr>
      <th>greeting</th>
      <td><span id="greeting">Good morning</span></td>
    </tr>
  </table>
  <a href="greetingInput.html" id="goBack">back</a>
</div>
</body>
</html>

greeting.mayaa

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org"
        xmlns:html="http://struts.apache.org/tags-html"
        xmlns:bean="http://struts.apache.org/tags-bean"
        xmlns:s2struts="http://www.seasar.org/tags-s2struts"
        m:noCache="true">

    <m:ignore id="appBody" />

    <bean:write m:id="time" name="greetingDto" property="time" />
    <bean:write m:id="greeting" name="greeting" />
    <html:link m:id="goBack" page="/greetingInput.html">back</html:link>

</m:mayaa>

これで作業は終了です。

Tomcatを再起動して、 ブラウザからhttp://localhost:8080/s2struts-blank/greetingInput.htmlにアクセスし動作を確認してください。

struts-config.xmlを編集していないですが動作します。 なぜなら、実行時にS2Strutsが規約に従いstruts-config情報を生成しているからです。 GreetingDtoとGreetingActionを作った時点で以下のstruts-configの記述と同等の作業を行ったことになります。

...
<form-beans>
    ...
    <form-bean
        name="greetingDto"
        type="examples.dto.GreetingDto" />
    ...
</form-beans>
...
<action-mappings>
    ...
    <action
        path="/greeting"
        type="examples.action.GreetingAction"
        name="greetingDto"
        scope="request"
        validate="true">
        <forward name="success" path="/greeting.html" />
    </action>
    ...
</action-mappings>
...

今回は規約に従うことができたので設定は不要でしたが、規約に従えない場合もあります。 その場合はアノテーションを使用して直接指定することができます。 規約とアノテーションについては「無設定S2Struts」を参照してください。

S2Strutsの世界はいかがでしたか? POJOのActionはテストしやすそうに見えませんか? もうアプリケーションの規模といっしょに大きくなっていくstruts-config.xmlに悩む必要はありません。 S2Strutsをより詳しく知りたい場合は、以下のリファレンスを参照してください。

S2Strutsリファレンス

基本的な使い方

まず、S2Containerを起動するためにS2ContainerServletをweb.xmlに登録する必要があります。 また、S2ContainerFilterとS2StrutsFilterを以下のように設定して下さい。

次に、org.apache.struts.action.ActionServletの替わりに、org.seasar.struts.servlet.S2ActionServletを、 org.apache.struts.actions.RedeployableActionServletの替わりであれば、org.seasar.struts.servlet.S2RedeployableActionServletを登録して下さい。

web.xml

<web-app>
  <display-name>Struts Application</display-name>

  <filter>
    <filter-name>s2filter</filter-name>
    <filter-class>
      org.seasar.framework.container.filter.S2ContainerFilter
    </filter-class>
  </filter>

  <filter>
    <filter-name>s2strutsfilter</filter-name>
    <filter-class>org.seasar.struts.filter.S2StrutsFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>s2filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter-mapping>
    <filter-name>s2strutsfilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>s2container</servlet-name>
    <servlet-class>
      org.seasar.framework.container.servlet.S2ContainerServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!-- Standard Action Servlet Configuration (with debugging) -->
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.seasar.struts.servlet.S2ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>s2container</servlet-name>
    <url-pattern>/s2container</url-pattern>
  </servlet-mapping>

  <!-- Standard Action Servlet Mapping -->
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  <!-- The Usual Welcome File List -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

S2とStrutsを連動させるためにS2用のRequestProcessorをstruts-config.xmlに登録する必要があります。 S2RequestProcessorとS2TilesRequestProcessorを用意しています。 これらはそれぞれStrutsのRequestProcessorとTilesRequestProcessorに相当します。

struts-config.xml

<struts-config>
  ...
  <controller processorClass="org.seasar.struts.processor.S2RequestProcessor"/>
  ...
</struts-config>

連動させたいActionクラスはコンポーネント定義に登録する必要があります。 Actionクラスを個別に登録することもできますが、個別に登録を行うとActionクラスを追加するたびにコンポーネント定義ファイルを修正しなければなりません。 その問題を避けるため、コンポーネントの自動登録を利用することを推薦します。

Multiply.dicon

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
  "http://www.seasar.org/dtd/components21.dtd">
<components>
  <component name="traceInterceptor"
      class="org.seasar.framework.aop.interceptors.TraceInterceptor"/>

  <component
      class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"org.seasar.struts.examples.multiply"</arg>
      <arg>".*ServiceImpl"</arg>
    </initMethod>
  </component>
  
  <component
      class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="instanceDef">
      @org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
    </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"org.seasar.struts.examples.multiply"</arg>
      <arg>".*Action"</arg>
    </initMethod>
  </component>
  <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
    <property name="interceptor">traceInterceptor</property>
    <initMethod name="addClassPattern">
      <arg>"org.seasar.struts.examples.multiply"</arg>
      <arg>".*Action"</arg>
    </initMethod>
  </component>
</components>

また、このコンポーネント定義ファイルはアプリケーション全体の定義であるapp.diconに登録する必要があります。

app.dicon

<components>
  ...
  <include path="org/seasar/struts/examples/dicon/Multiply.dicon"/>
  ...
</components>

これでRequestProcessorにより生成される全てのActionクラスがS2と連動するようになります。

インターフェースに対するセッターメソッドを定義しておけば、 自動的にセッター・インジェクションが行われます。 また、インターフェースのみが引数のコンストラクタを定義している場合は、 自動的に、コンストラクタ・インジェクションが行われます。

サービスコンポーネントを受け取るためにActionクラスはコンストラクタもしくはセッターメソッドを定義しておきます。 execute()メソッドでは、サービスに処理を委譲するのみとなるので、非常にすっきりしたコードになっていることが分かると思います。

MultiplyAction

package org.seasar.struts.examples.multiply;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.seasar.struts.examples.form.CalculationForm;

public class MultiplyAction extends Action {

    private MultiplyService multiplyService_;

    public MultiplyAction(MultiplyService multiplyService) {
        multiplyService_ = multiplyService;
    }

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

        CalculationForm calForm = (CalculationForm) form;
        int result = multiplyService_.multiply(calForm.getArg1(), calForm.getArg2());
        calForm.setResult(result);
        return (mapping.findForward("success"));
    }
}

ActionをPOJOにした使い方

org.apache.struts.action.Actionを継承しないPOJOをActionとして使用する事が出来ます。

以下のように、インターフェースと、実装クラスを作成し実装クラスは、コンポーネント定義ファイルに定義して下さい。 アクションメソッドの戻り値は、Stringとして、forward名を返すようにして下さい。 そして、struts-configには、インターフェースをactionタグのtype属性に指定して下さい。

EchoAction

public interface EchoAction {
	String echo();
}

EchoActionImpl

public class EchoActionImpl implements EchoAction {
    private StringForm strForm;
    
    public EchoActionImpl() {
    }

    public String echo() {
        strForm.setResult(strForm.getInput());
        
        return FowardNameConstants.SUCCESS;
    }

    public StringForm getStrForm() {
        return strForm;
    }
    public void setStrForm(StringForm strForm) {
        this.strForm = strForm;
    }
}

POJOアクションクラスに、セッターメソッドがある場合、HttpServletRequestまたは、HttpSessionの値が、自動バインディングされます。
値を参照する際の優先順位は次の通りです。
(1)HttpServletRequest#getParameter(プロパティー名)
(2)HttpServletRequest#getAttribute(プロパティー名)
(3)HttpSession#getAttribute(プロパティー名)

1.3.0-RC3以降では優先順位が変更されて次のようになっています(1番目と2番目の優先順位が入れ替わりました)。
(1)HttpServletRequest#getAttribute(プロパティー名)
(2)HttpServletRequest#getParameter(プロパティー名)
(3)HttpSession#getAttribute(プロパティー名)

また、パラメーターに[]が付き、foo[0]=fooVal0,foo[1]=fooVal1のようなパラメーターを受け取った場合には、

setFoo(int index, Object value);
のように、第一引数にint、第二引数に値を持ったインデックス付きのセッターメソッドが自動バインディングの対象になります。

また、getterメソッドがある場合も同様に、HttpServletRequestまたは、HttpSessionに値を自動バインディングします。
(1)基本的に、HttpServletRequest#setAttribute(プロパティー名,プロパティー値)を行います。
(2)HttpSession#setAttribute(プロパティー名,プロパティー値)を行いたい場合は、定数アノテーションにて、

public final static String プロパティ名_EXPORT = org.seasar.struts.Constants.SESSION;
とActionクラスに記述する必要があります。

また、アノテーションによる記述も可能です。その記述方法については、以下の方法でゲッターメソッドに対しアノテーションを記述する事で可能になります。

@ExportToSession()
public String getFoo() {
    return foo;
}
以下のように、backport175による記述も可能です。
/**
 * @org.seasar.struts.annotation.backport175.ExportToSession()
 */
public String getFoo() {
    return foo;
}

Echo.dicon

<components>
	<component class="org.seasar.struts.examples.echo.EchoActionImpl" instance="request"/>
</components>

struts-config.xml

<struts-config>
  ...
  <action-mappings>
    ...
    <action
      path="/echo"
      type="org.seasar.struts.examples.echo.EchoAction"
      name="strForm"
      scope="request"
      validate="false"
      input="/pages/echoInput.jsp">
      <forward name="success" path="/pages/strResult.jsp" />
    </action>
    ...
  <action-mappings>
  ...
</struts-config>

実装クラスのプロパティーは、web.xmlにS2ContainerFilterを登録しておく事によって、リクエストまたは、セッションとActionに対し、相互に自動バインディングされます。 リクエストとセッションのどちらにバインディングされるかは、コンポーネント定義ファイルのinstance属性により決定されます。ActionFormに関しては、struts-config.xmlに定義したscope属性により決定します。

また、インターフェースのメソッドが複数存在する場合には、org.apache.struts.actions.DispatchActionを使用する場合と同様に、 struts-config.xmlのactionタグにparameter属性の追加と、JSPのサブミットボタンに対し、name属性とvalue属性の2つの属性で、メソッドを指定して下さい。

ChangeCaseAction

public interface ChangeCaseAction {
    String toLowerCase();

    String toUpperCase();
}

struts-config.xml

<struts-config>
  ...
  <action-mappings>
    ...
    <action
      path="/changeCase"
      type="org.seasar.struts.examples.changecase.ChangeCaseAction"
      name="strForm"
      scope="request"
      validate="true"
      parameter="command"
      input="/pages/changeCaseInput.jsp">
      <forward name="success" path="/pages/strResult.jsp" />
    </action>
    ...
  <action-mappings>
  ...
</struts-config>

changeCaseInput.jsp

...
<html:submit property="command"><bean:message key="toLowerCase"/></html:submit>
<p>
<html:submit property="command"><bean:message key="toUpperCase"/></html:submit>
...

HTMLに変換されると以下のようになります。

<input type="submit" name="command" value="toLowerCase">
<p>
<input type="submit" name="command" value="toUpperCase">

ProxyActionクラスの使い方

また、ProxyActionクラスを使用して、コンポーネント定義ファイルに記述したActionを呼び出し、処理を委譲する事もできます。 これにより、struts-configとコンポーネント定義ファイルに同じクラス名を定義/同期する必要がなくなります。 struts-config内に記述しているactionのpath属性と、コンポーネント定義ファイルに定義したcomponentのname属性が一致している必要があります。 詳細は、「path属性とActionクラスのマッピングについて」を参照してください。

また、ProxyActionクラスのみに関しては、struts-configに、S2用のRequestProcessorを登録しなくとも、S2と連動する事ができます。 ただし、他のActionクラスもS2と連動させたい場合には、前述のように、S2用のRequestProcessorをstruts-config.xmlに登録する必要があります。 これは、特定のActionクラスのみを、S2と連動する為に有効である事を意味します。

struts-config.xml

<struts-config>
  ...
  <action-mappings>
    ...
    <action
      path="/subtract"
      type="org.seasar.struts.action.ProxyAction"
      name="calcForm"
      scope="request"
      validate="false"
      input="/pages/subtractInput.jsp">
      <forward name="success" path="/pages/result.jsp" />
    </action>
    ...
  <action-mappings>
  ...
</struts-config>

Subtract.dicon

<components>
  <component name="/subtract" class="org.seasar.struts.examples.SubtractAction"/>
  <component class="org.seasar.struts.examples.SubtractServiceImpl"/>
</components>

struts-config内に記述しているactionの、type属性を記述せずにActionクラスを指定する

ProxyActionクラスの使い方と同様に、struts-config内に記述しているactionのpath属性と、 コンポーネント定義ファイルに定義したcomponentのname属性を一致させる事によりtype属性を記述せずにActionクラスを呼び出す事が出来ます。 詳細は、「path属性とActionクラスのマッピングについて」を参照してください。 この手法を利用する為には条件があります。それは、type属性、forward属性、include属性の3つの属性が無い事です。 これにより、struts-configとコンポーネント定義ファイルに同じクラス名を定義/同期する必要がなくなります。

struts-config.xml

<struts-config>
  ...
  <action-mappings>
    ...
    <action
      path="/divide"
      name="calcForm"
      scope="request"
      validate="false"
      input="/pages/divideInput.jsp">
      <forward name="success" path="/pages/result.jsp" />
    </action>
    ...
  <action-mappings>
  ...
</struts-config>

Divide.dicon

<components>
  <component name="/divide" class="org.seasar.struts.examples.DivideAction"/>
  <component class="org.seasar.struts.examples.DivideServiceImpl"/>
</components>

path属性とActionクラスのマッピングについて

ここでは、前述の「ProxyActionクラスの使い方」と、 「struts-config内に記述しているactionの、type属性を記述せずにActionクラスを指定する」で行った、 path属性とActionクラスのマッピングについての、詳細情報を記述します。

以下の、web.xml、struts-config、そして、コンポーネント定義ファイルが存在するとします。

web.xml

<web-app>
  ...
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>config/foo</param-name>
      <param-value>/WEB-INF/struts-config-foo.xml</param-value>
    </init-param>
    ...
  </servlet>
  ...
</web-app>

struts-config.xml

<struts-config>
  ...
  <action-mappings>
    ...
    <action path="/bar"
      ...
    </action>
    ...
  <action-mappings>
  ...
</struts-config>

struts-config-foo.xml

<struts-config>
  ...
  <action-mappings>
    ...
    <action path="/baz"
      ...
    </action>
    ...
  <action-mappings>
  ...
</struts-config>

コンポーネント定義ファイル

<components>
  <component name="/bar" class="BarAction"/>
  <component name="/foo/baz" class="BazAction"/>
</components>

デフォルトのモジュール(struts-config.xmlで動作するモジュール)であれば、struts-config内に記述しているactionタグのpath属性と、 コンポーネント定義ファイル内に記述しているcomponentタグのname属性でマッピングを行います。下記のサブモジュールの(2)のパターンになります。

サブモジュール(この例では、struts-config-foo.xmlで動作するモジュール)であれば、マッピング方法が2つ存在します。

    (1)モジュール(prefix)名(/foo)+path属性(/baz)=name属性(/foo/baz
    (2)path属性(/baz)=name属性(/baz
コンポーネントを取得する優先順位は、(1)、(2)の順になります。つまり、名前が/foo/bazであるコンポーネントが見つからなければ、名前が/bazであるコンポーネントを取得します。

また、org.seasar.struts.ComponentNameCreatorをimplementsしたクラスを作成し、app.diconから登録する事で、上記のデフォルトのマッピング方法を替える事が出来ます。

適用へのヒント

メリット・デメリット


メリット デメリット
POJOAction(推奨) テスタビリティー向上
Actionクラスのモックの切り替えが容易になる
S2JSFなどへの移行も容易になる
インターフェースを定義したファイルが増える可能性がある (ただし、The Seasar Foundationでは、他からアクセスされるときのインターフェースは明示的であるほうが保守性は高くなると考えています)
Multiplyの例 既存のAction、struts-configのaction-mappingを修正しないで使用することができる

Subtract(ProxyAction)の例 ActionMappingの情報(デフォルトは、パス名)から、コンポーネントを検索するため、 struts-configとコンポーネント定義ファイルに書いてあるActionのクラス名を同期する必要なし
クラスが継承関係にあるAction同士をコンテナに登録する事が可能
ActionMappingの情報と、コンポーネント名を同期する必要あり
Divideの例 同上。struts-configに、type属性(Actionのクラス名)を記述する必要がないので、記述量は減る 同上。ただし、Struts的には、間違ったstruts-configの記述の仕方のため、struts-configを記述するツールとの連携が取れない可能性がある

特に理由のない場合は、POJOActionを使用する事を推奨します。

RequestProcessorをコンポーネントから取得する

Actionクラスに共通のアスペクトを適用するのと同様の事が、RequestProcessorをコンポーネントから取得することによって可能になります。 また、アスペクトの適用以外にも他のコンポーネントと同様の使い方もすることが出来ます。

まず、S2ActionServletをweb.xmlに登録する必要があります。 web.xmlに記述するサーブレットをorg.apache.struts.action.ActionServletではなく、 org.seasar.struts.action.S2ActionServletもしくは、org.seasar.struts.action.S2RedeployableActionServletと記述してください。 (S2ActionServletは、ActionServletを継承、S2RedeployableActionServletは、RedeployableActionServletを継承したサーブレットとなっています。)

web.xml

<web-app>
  ...
  <!-- Standard Action Servlet Configuration (with debugging) -->
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.seasar.struts.action.S2ActionServlet</servlet-class>
    ...
  </servlet>
  ...
</web-app>

今回の例では、S2RequestProcessorにMeasureTimeInterceptorというアスペクトを適用することで、 各リクエストの処理時間を測定し標準出力しています。

RequestProcessor.dicon

<components>
  <include path="s2struts.dicon"/>
  <component class="org.seasar.struts.S2RequestProcessor">
    <aspect pointcut="process">
      <component class="org.seasar.struts.examples.MeasureTimeInterceptor">
    </aspect>
  </component>
</components>

エラーメッセージの表示を任意のコンポーネントから管理する

org.seasar.struts.action.MessageManagerクラスを利用すると任意のコンポーネントからエラーメッセージの表示を管理する事が可能になります。

MessageActionImpl.java

public class MessageActionImpl implements MessageAction {

    public String execute() {
        MessageManager.addGlobalError("examplemessage");
        MessageManager.addGlobalError("examplemessage", "foo");
        MessageManager.addGlobalError("examplemessage", "bar", "baz", "qux");
        MessageManager.addError("property", "examplemessage");
        MessageManager.addError("property", "examplemessage", "foo");
        MessageManager.addError("property", "examplemessage", "bar", "baz", "qux");
        MessageManager.saveErrors();

        return FowardNameConstants.SUCCESS;
    }

}

これは、StrutsのActionクラスで実装する以下のコードとほぼ同意です。

  ActionMessages errors = new ActionMessages();
  errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage"));
  errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage", "foo"));
  errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage", "bar", "baz", "qux"));
  errors.add("property",new ActionMessage("examplemessage"));
  errors.add("property",new ActionMessage("examplemessage", "foo"));
  errors.add("property",new ActionMessage("examplemessage", "bar", "baz", "qux"));
  if(!errors.isEmpty()) {
      saveErrors(request,errors);
  }

"ほぼ"同意と記述した理由は、上記で利用するリソースのキーexamplemessageの中に、{4}などが含まれていた場合にそれを削除する機能がMessageManagerには備わっている為です。

また、MessageManagerは、メッセージを管理するためのaddGlobalMessage()、addMessage()メソッドや、saveMessages()メソッドも備えています。 引数などはエラーメッセージを扱う場合と同じです。

無設定S2Strutsリファレンス

S2Strutsを使用すると、規約に従ってstruts-configを自動的に補完します(無設定S2Struts)。 アノテーションを使ってstruts-configを指定した内容で補完することも可能です。 これによりstruts-configによる設定を省略する事が可能になります。

無設定S2Struts

無設定S2Strutsの機能を利用するためには、struts-configにAutoStrutsConfigRegisterPlugInを登録する必要があります。 PlugInには読み込み順があるのでValidatorPlugInより後に登録してください。

struts-config.xml

<struts-config>
  ...
  <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    ...
  </plug-in>
    
  <plug-in className="org.seasar.struts.plugin.AutoStrutsConfigRegisterPlugIn">
    <set-property property="enableJar" value="false"/>
    <set-property property="jarFilePattern" value="^My.*\.jar$"/>
    <set-property property="actionClassPattern" value="foo.bar.action.*Action"/>
    <set-property property="formClassPattern" value="foo.bar.form.*Form"/>
    <set-property property="docRoot" value="/WEB-INF/jsp"/>
    <set-property property="viewExtension" value="jsp,html,view"/>
  </plug-in>
  ...
</struts-config>

プラグインのプロパティーには値をセットすることが可能です。各プロパティーの説明は以下になります。各プロパティーの記述を省略した場合にはデフォルト値が使用されます。

プロパティー 説明 デフォルト値
enableJar 無設定S2Strutsに含めるクラスをクラスパスに含まれているjarファイル内からも検索するか指定します。検索する場合、true。 false
jarFilePattern enableJarをtrueとしたときに検索するjarファイルのファイル名パターンを指定します。 なし
(どのjarファイルも検索対象になりません)
referenceClass 指定されたクラスが存在するディレクトリまたはjarファイルを基点として自動登録するクラスを検索します。 なし
actionClassPattern 無設定S2Strutsでactionタグの値を特定するためのActionのクラス名のパターンを指定します。 .*Action$
formClassPattern 無設定S2Strutsでform-beanタグの値を特定するためのActionFormのクラス名のパターンを指定します。 (.*Form$)|(.*Dto$)
docRoot Viewテンプレートとなるファイルの置き場所のトップディレクトリを指定します。 なし
viewExtension Viewテンプレートとなるファイルの拡張子を指定します。 jsp,html

無設定S2Strutsで省略可能な値はform-beanタグの属性、またactionタグとそのactionタグ内のforwardタグの属性になります。 デフォルトで提供する規約に従った場合の各属性値がどのようになるのか以下に記述します。

form-beanタグの属性値

クラス名が"Form"あるいは"Dto"で終了しているクラスを基に設定を補完します。

属性 デフォルトの規約による値
type クラス名
name クラス名からS2に登録されたコンポーネントを検索し、コンポーネント名使用します。
restricted false

actionタグの属性値

クラス名が"Action"で終了しているクラスを基に設定を補完します。

属性 デフォルトの規約による値
type クラス名
path クラス名からS2に登録されたコンポーネントを検索します。
コンポーネント名が"/"から始まっている場合はそのまま利用します。
"/"から始まっていない場合は先頭に"/"を付加し、 最後が次の値の場合にその値を削除します。その値とは、"ActionImpl"、"Impl"、"Action"の3つです。
コンポーネント名が見つからない場合は、クラス名の先頭を小文字にした値をコンポーネント名とし上記の設定をします。
name path属性の先頭の"/"を削除した値を設定します。
scope request
validate true
input 設定しない(null)
parameter 設定しない(null)
attribute 設定しない(null)
forward 設定しない(null)
include 設定しない(null)
prefix 設定しない(null)
suffix 設定しない(null)
unknown 設定しない(false)
roles 設定しない(null)
cancellable false

actionタグ内のforwardタグの属性値

クラス名が"Action"で終了しているクラスを基に設定を補完します。
属性 デフォルトの規約による値
name success(変更不可)
path 次に説明する手順によりpathを設定します。
1.パッケージ名の"."を"/"に変更し、その値とクラス名を連結します(アクション名を連結します)。
2.クラス名の最後が次の値の場合にその値を削除します。その値とは、"ActionImpl"、"Impl"、"Action"の3つです。連結する際にクラス名の先頭を小文字にします。
3.AutoStrutsConfigRegisterPlugInのdocRootに指定した値を先頭に付加します。
4.".html"と".jsp"を拡張子にしたファイル検索し、ファイルが存在すればpathに設定します。
5.ファイルが見つからない場合は、パッケージにあたる2番目の"/"の直前までを削除した文字列を使用し上記"4"を行います。
6.最終的に見つからなかった場合は、設定を行わずログに出力します。

例えば、
クラス:aaa.bbb.ccc.HogeAction
AutoStrutsConfigRegisterPlugInのdocRoot:/jsp
の場合、pathに設定するファイルの検索順は
1)/jsp/aaa/bbb/ccc/hoge.jsp
2)/jsp/bbb/ccc/hoge.jsp
3)/jsp/ccc/hoge.jsp
4)/jsp/hoge.jsp
となります。
redirect 設定しない(false)

アノテーションを使用したstruts-configの設定

Tigerを用いたアノテーションの記述とbackport175を用いたアノテーションの記述の2通りの記述が可能です。この2通りのアノテーションを同時に使用する事は出来ません。 それぞれを使用するためには、以下の表に示したjarファイルが必要です。

Annotation必要なjarファイル(x.x.xはバージョン)
Tigers2-struts-tiger-x.x.x.jar
backport175s2-struts-backport175-x.x.x.jar

以下のようにActionにアノテーションを記述することによりstruts-configの設定を行うことが出来ます。

package org.seasar.struts.examples.employee.action;

import org.seasar.struts.annotation.tiger.StrutsAction;
import org.seasar.struts.annotation.tiger.StrutsActionForward;

@StrutsAction(name="employeeForm", validate=false)
public interface EmployeeEditAction {

	@StrutsActionForward(path="/pages/employee/employeeEdit.jsp")
	public String SUCCESS = "success";

	public String execute();

}
backport175を使用したアノテーションの記述では以下のようになります。
package org.seasar.struts.examples.employee.action;

/**
 * @org.seasar.struts.annotation.backport175.StrutsAction(
 *   name="employeeForm", validate=false)
 */
public interface EmployeeEditAction {

	/**
	 * @org.seasar.struts.annotation.backport175.StrutsActionForward(
	 *         path="/pages/employee/employeeEdit.jsp")
	 */
	public String SUCCESS = "success";

	public String execute();

}
定数アノテーションの記述では以下のようになります。
package org.seasar.struts.examples.employee.action;

public interface EmployeeEditAction {

	public static final String ACTION = "name=employeeForm, validate=false";

	public static final String SUCCESS_FORWARD = "path=/pages/employee/employeeEdit.jsp";

	public String SUCCESS = "success";

	public String execute();

}
これらは、以下の記述と同等になります。
...
<action-mappings>
    ...
    <action
        path="/employeeEdit"
        type="org.seasar.struts.examples.employee.action.EmployeeEditAction"
        name="employeeForm"
        scope="request"
        validate="true">
        <forward name="success" path="/pages/employee/employeeEdit.jsp" />
    </action>
    ...

StrutsAction(ACTION)で指定可能な属性

属性必須
path
×
name
×
scope
×
validate
×
input
×
parameter
×
attribute
×
forward
×
include
×
prefix
×
suffix
×
unknown
×
roles
×
cancellable
×
struts-configのactionタグの属性と対になります。また、各属性のデフォルト値は、無設定S2Strutsで定義される値になります。

StrutsActionForward(FORWARD)で指定可能な属性

属性必須デフォルト値
path
-
redirect
×
false
struts-configのforwardタグの属性と対になります。定数値でname属性を指定します。

また、以下のようにForm(DTO)にアノテーションを記述することによりstruts-configの設定を行うことが出来ます。

package org.seasar.struts.examples.employee.dto;

import org.seasar.struts.annotation.tiger.StrutsActionForm;

@StrutsActionForm(name="employeeForm")
public class EmployeeDto extends Employee {
	...
}
backport175を使用したアノテーションの記述では以下のようになります。
package org.seasar.struts.examples.employee.dto;

/**
 * @org.seasar.struts.annotation.backport175.StrutsActionForm(name="employeeForm")
 */
public class EmployeeDto extends Employee {
	...
}
定数アノテーションの記述では以下のようになります。
package org.seasar.struts.examples.employee.dto;

public class EmployeeDto extends Employee {

	public static final String FORM = "name=employeeForm";
	...
}
これらは、以下の記述と同等になります。
...
<form-beans>
    ...
    <form-bean
        name="employeeForm"
        type="org.seasar.struts.examples.employee.dto.EmployeeDto" />
    ...

StrutsActionForm(FORM)で指定可能な属性

属性必須
name
×
restricted
×
struts-configのform-beanタグの属性と対になります。また、各属性のデフォルト値は、無設定S2Strutsで定義される値になります。

アノテーションを使用したvalidationの設定

以下のようにActionFormのセッターメソッドにアノテーションを記述することによりvalidationの設定を行うことが出来ます。

public class ValidateDto implements Serializable {

    private String value;

    @ValidateOrder(1)
    @Required
    @Minlength(10)
    @Maxlength(15)
    @Mask(pattern="com$",messageKey="mustendcom")
    @EmailType
    @Args(keys="mixValue",resource=false)
    public void setValue(String value) {
        this.value = value;
    }
backport175を使用したアノテーションの記述では以下のようになります。
public class ValidateDto implements Serializable {

    private String value;

    /**
     * @org.seasar.struts.validator.annotation.backport175.ValidateOrder(1)
     * @org.seasar.struts.validator.annotation.backport175.Required
     * @org.seasar.struts.validator.annotation.backport175.Minlength(value=10)
     * @org.seasar.struts.validator.annotation.backport175.Maxlength(value=15)
     * @org.seasar.struts.validator.annotation.backport175.Mask(
     *    pattern="com$",messageKey="mustendcom")
     * @org.seasar.struts.validator.annotation.backport175.Email
     * @org.seasar.struts.validator.annotation.backport175.Args(
     *    keys="mixValue",resource=false)
     */
    public void setValue(String value) {
        this.value = value;
    }
}
定数アノテーションの記述では以下のようになります。
public class ValidateDto implements Serializable {

    private String value;

    public static final int value_VALIDATOR_ORDER = 1;
    public static final String value_VALIDATOR = "required";
    public static final String value_VALIDATOR_0 = "minlength, value=10";
    public static final String value_VALIDATOR_1 = "maxlength, value=15";
    public static final String value_VALIDATOR_2 = "mask, pattern=com$, messageKey=mustendcom";
    public static final String value_VALIDATOR_3 = "email";
    public static final String value_VALIDATOR_ARGS = "keys=mixValue, resource=false";

    public void setValue(String value) {
        this.value = value;
    }
}

S2Strutsでは、validation設定のために各種アノテーションを用意しています。 ValidateOrder、Args、Message以外のアノテーションは基本的なバリデータを行うために利用します。

ValidateOrder

検証する順番を制御します。指定した順番でエラーメッセージを表示します。

属性必須デフォルト値説明
value
×
999
検証する順番を指定します。

Args

メッセージで使用される置換パラメータを指定します。

属性必須デフォルト値説明
keys
×
-
メッセージで使用される置換パラメータを指定します。
","で区切ることにより複数指定できます。
定数アノテーションで","で区切る方法については「定数アノテーションの補足」を参照してください。
bundle
×
-
デフォルト以外のメッセージリソースを使用する場合、 使用するメッセージリソースのキーを指定します。
resource
×
true
keysで指定した値をリソースキーとして利用するかを指定します。
trueの場合はリソースキーとして利用し該当する値を置換パラメータとします。
falseの場合はkeysで指定した値をそのまま置換パラメータとします。
value
×
-
Argアノテーションで個別に置換パラメータを指定する場合に使用します。
個別に置換パラメータを指定する場合は、keys、bundle、resourceを指定しないで下さい。

Arg

メッセージで使用される置換パラメータを個別に指定します。

属性必須デフォルト値説明
key
-
メッセージで使用される置換パラメータを指定します。
name
×
-
置換パラメータを使用するバリデータの名前を指定します。
bundle
×
-
デフォルト以外のメッセージリソースを使用する場合、 使用するメッセージリソースのキーを指定します。
resource
×
true
keyで指定した値をリソースキーとして利用するかを指定します。
trueの場合はリソースキーとして利用し該当する値をメッセージとします。
falseの場合はkeyで指定した値をそのままメッセージとします。
position
×
-
置換パラメータの位置を指定します。

定数アノテーションでは、以下のように プロパティー名_VALIDATOR_ARG で指定します。 複数指定する場合は、定数名の最後にゼロからのINDEXをつけます。

    public static final String value_VALIDATOR_0 = "required";
    public static final String value_VALIDATOR_1 = "integer";
    public static final String value_VALIDATOR_ARG_0 = "form.value";
    public static final String value_VALIDATOR_ARG_1 = "form.value.def";
    public static final String value_VALIDATOR_ARG_2 = "form.value.req, name = required, position = 1";

    public void setValue(String value) {
        this.value = value;
    }

Messages

複数のMessageアノテーションを指定したい場合に使用します。

属性必須デフォルト値説明
value
-
複数のMessageアノテーションを指定します。

Message

デフォルトメッセージの代わりに個別のメッセージを表示したい場合に指定します。

属性必須デフォルト値説明
key
-
メッセージのキー又はメッセージを指定します。
name
-
メッセージを指定するバリデータの名前を指定します。
bundle
×
-
デフォルト以外のメッセージリソースを使用する場合、 使用するメッセージリソースのキーを指定します。
resource
×
true
keyで指定した値をリソースキーとして利用するかを指定します。
trueの場合はリソースキーとして利用し該当する値をメッセージとします。
falseの場合はkeyで指定した値をそのままメッセージとします。

Required

値に空白以外の文字が含まれてるか確認します。 引数はありません。

Mask

値がpatternで指定された正規表現と一致するか確認します。

属性必須デフォルト値説明
pattern
-
正規表現を指定します。
messageKey
×
-
メッセージを取得するキーを指定します。
resource
×
true
keysで指定した値をリソースキーとして利用するかを指定します。
trueの場合はリソースキーとして利用し該当する値を置換パラメータとします。
falseの場合はkeysで指定した値をそのまま置換パラメータとします。

IntRange, LongRange, FloatRange, DoubleRange

値がminとmaxで指定された範囲内であるか確認します。

属性必須デフォルト値説明
min
-
値範囲の最小値を指定します。
max
-
値範囲の最大値を指定します。

Maxlength

値の文字数がvalue以下であるか確認します。

属性必須デフォルト値説明
value
-
値の長さの上限値を指定します。

Minlength

値の文字数がvalue以上であるか確認します。

属性必須デフォルト値説明
value
-
値の長さの下限値を指定します。

Maxbytelength

値のバイト数がvalue以下であるか確認します。

属性必須デフォルト値説明
value
-
値の長さの上限値を指定します。
charset
×
-
バイト数で検証する場合の文字セットを指定します。
指定しない場合は、プラットフォームのデフォルト文字セットを使用します。

Minbytelength

値のバイト数がvalue以上であるか確認します。

属性必須デフォルト値説明
value
-
値の長さの下限値を指定します。
charset
×
-
バイト数で検証する場合の文字セットを指定します。
指定しない場合は、プラットフォームのデフォルト文字セットを使用します。

ByteType, ShortType, IntegerType, LongType, FloatType, DoubleType

値が該当する型に変換できるか確認します。 属性はありません。

DateType

値が有効な日付を表すか確認します。

属性必須デフォルト値説明
pattern
×
s2struts.dionのdateConfigRegisterコンポーネント定義時に指定したパターン
日付のパターンを指定します。

CreditCardType

値が有効なクレジットカード番号とみなされるか確認します。 属性はありません。

EmailType

値が有効なEメールアドレスとみなされるか確認します。 属性はありません。

UrlType

値が有効なURLとみなされるか確認します。

属性必須デフォルト値説明
allowallschemes
×
false
schemeを許可するかどうかを指定します。
trueを設定するとすべてのschemeが許可されます。
allow2slashes
×
false
ダブルスラッシュ(//)を許可するかどうかを指定します。
trueを設定すると許可されます。
nofragments
×
false
URLの分割を許可するかどうかを指定します。
falseを設定すると許可されます。
schemes
×
http,https,ftp
許可するschemeを,(カンマ)区切りで指定します。

NoValidate

自動的にバリデーションを行わないように指定します。 属性はありません。

定数アノテーションの補足

定数アノテーションでは、属性の区切り文字として「,」(カンマ)を利用しています。 値に「,」を指定する場合は以下のように値を「'」(シングルコーテーション)または「"」(ダブルコーテーション)で囲んでください。

 public static final String value_VALIDATOR = "mask, pattern='(^[0-9]{1,2}$)', messageKey=comma";

 public static final String value_VALIDATOR = "mask, pattern=\"(^[0-9]{1,2}$)\", messageKey=comma";

S2Strutsタグライブラリリファレンス

S2Strutsでは、ButtonTagとSubmitTagを用意しています。 どちらも、Strutsのタグを拡張した形となっています。

buttonタグ

org.seasar.struts.taglib.html.ButtonTag(タグ名:button)

http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#button
に加えて、追加になった属性は、以下です。

属性名必須rtexprvalue説明
type
×
false
以下の値で、ボタンの種別を指定します。
"button":通常のボタン。
"submit":実行ボタン。
"reset":リセットボタン。
HTML4.01 では submit が規定値と定義されていますが、
IE6.0 や Netscape の実装では規定値は button のようです。
indexId
×
false
logic:iterateタグのid属性などで指定した変数名を指定します。
buttonのvalue属性の値に、その変数の値が設定されます。
(変数値が、Integerの32である場合の変換されたhtmlの例:<button ... value="32" ...>)

submitタグ

org.seasar.struts.taglib.html.SubmitTag(タグ名:submit)

http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#submit
に加えて、追加になった属性は、以下です。

属性名必須rtexprvalue説明
action
×
-
action="#{component.method}"と記述することによって、サブミット時に実行するコンポーネントとメソッドを指定する事が可能です。 コンポーネントは、この属性で指定した名前でS2Containerに登録されている必要があります。
indexId属性を指定しない場合は、引数なしとして指定されたメソッドを呼び出します。
例えば、<s2struts:submit action="{hogeAction.create}"> と記述して表示されたボタンを押した場合、 String create() メソッドが呼び出されます
indexId属性を指定した場合は、int型のindexを引数とする指定されたメソッドを呼び出します。
例えば、<s2struts:submit action="{hogeAction.create}" indexId="index"> と記述して表示されたボタンを押した場合、 String create(int index) メソッドが呼び出されます。

S2Struts1.3.0-RC3以降では、指定したコンポーネントに対応するActionMappingが使用されます。 ActionMappingは、デフォルトではActionPathNamingRuleコンポーネントから求められるpathをキーにして決定されます。 明示的に指定する場合は呼び出すメソッドにBINDING_METHODアノテーションを指定してください。
indexId
×
false
logic:iterateタグのid属性などで指定した変数名を指定します。
propertyName[変数値]の様に変換されます。
(変数値が、Integerの32である場合の変換されたhtmlの例:<... foo[32]="bar"...>)
cancel
×
false
trueを指定した場合、フォームに関連付けされたActionFormのvalidateを無視し、 アクションを呼び出します。

cancelタグ

org.seasar.struts.taglib.html.CancelTag(タグ名:cancel)

http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#cancel
を拡張し、Requestパラメーターを利用しないでCancel機能を実現したタグです。 追加した属性はありません。

imageタグ

org.seasar.struts.taglib.html.ImageTag(タグ名:image)

http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#image
に加えて、追加になった属性は、以下です。

属性名必須rtexprvalue説明
action
×
-
action="#{component.method}"と記述することによって、サブミット時に実行するコンポーネントとメソッドを指定する事が可能です。 コンポーネントは、この属性で指定した名前でS2Containerに登録されている必要があります。

S2Struts1.3.0-RC3以降では、指定したコンポーネントに対応するActionMappingが使用されます。 ActionMappingは、デフォルトではActionPathNamingRuleコンポーネントから求められるpathをキーにして決定されます。 明示的に指定する場合は呼び出すメソッドにBINDING_METHODアノテーションを指定してください。
cancel
×
false
trueを指定した場合、フォームに関連付けされたActionFormのvalidateを無視し、 アクションを呼び出します。

checkboxタグ

org.seasar.struts.taglib.html.CheckboxTag(タグ名:checkbox)

http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#checkbox
を拡張し、チェックがない場合でもフォームに関連付けされたActionFormのプロパティにfalseを設定します。 追加した属性はありません。

pageタグ

org.seasar.struts.taglib.html.PageTag(タグ名:page)

このタグをJSPに記述することによって、struts-configのinput属性の無設定化(エラー時に自画面を再表示)することが可能になります。 formタグの中に記述する必要があります。複数のformが存在する場合には、それぞれに記述が必要です。

属性名必須rtexprvalue説明
-
-
-
属性はありません。

initタグ

org.seasar.struts.taglib.InitializeTag(タグ名:init)

このタグを使用すると画面の初期化処理を行う事が可能です。action属性に記述したMethodBindingを、JSPを表示する時に実行します。

属性名必須rtexprvalue説明
action
×
-
action="#{component.method}"と記述することによって、JSPを表示する時に実行するコンポーネントとメソッドを指定する事が可能です。 コンポーネントは、この属性で指定した名前でS2Containerに登録されている必要があります。

BINDING_METHODアノテーション

S2Struts1.3.0-RC3以降で利用できます。

BINDING_METHODアノテーションは、submitタグやimageタグで指定されたactionに対するActionMappingを明示的に指定するために使用します。

定数アノテーション

次の形式でstaticフィールドとしてActionに定義します。

public static final String メソッド名_BINDING_METHOD = "path=ActionMappingのpath"

タグとJavaの定義例は次の通りです。
<s2struts:submit action="#{modAction.mod}" property="submit" value="サブミット"/>
public static final String mod_BINDING_METHOD = "path=/hoge";

public String mod() {
  ...
}

Tigerアノテーション

次の形式でActionメソッドにアノテーションを指定します。

@BindingMethod(path = "ActionMappingのパス")

タグとJavaの定義例は次の通りです。
<s2struts:submit action="#{modAction.mod}" property="submit" value="サブミット"/>
@BindingMethod(path = "/hoge")
public String mod() {
  ...
}