MultiActionControllerを使って1つのControllerに複数のアクションをまとめることができ、これによって機能的にグルーピングすることが可能。メソッド名によってリクエストをマッピングすることができる。
呼び出すメソッドは以下の形式になっていなければならない。
public [ModelAndView | Map | void] メソッド名(HttpServletRequest, HttpServletResponse [, Exception | AnyObject]);
メソッドのオーバーロードは許されていない。さらに、メソッドを使っての例外ハンドリングも可能。Exception引数にはExceptionやRuntimeExceptionのサブクラスを指定できる。AnyObjectにはどんなクラスも指定できる。
設定できる項目
delegate | MultiActionControllerには使用方法が2つある。サブクラスでMethodNameResolverを使ってメソッド名を解決する方法(この場合は、delegateを設定する必要はない)。もしくは、メソッドの解決のためにdelegateオブジェクトを定義する方法。後者を選んだ場合、このdelegateパラメタを使って定義しなければならない |
methodNameResolver | MultiActionControllerは、やってくるリクエストからメソッドを実行するため解決方法としてMethodNameResolverインタフェースを使う。これを解決するために、このパラメタを利用する。 |
MethodNameResolver
- ParameterMethodNameResolver
- リクエストパラメタから解決可能。例えば「https://atomic-temporary-22783153.wpcomstaging.com/index.view?testParam=testIt」というリクエストがきた場合、「testIt()」というメソッドが呼ばれる。paramNameプロパティで調べるパラメタ名を規定する。
- InternalPathMethodNameResolver
- リクエストパスからファイル名を取り出し、メソッド名として使う。例えば「https://atomic-temporary-22783153.wpcomstaging.com/testing.view」というリクエストが着たら、「testing()」が呼ばれる。
- PropertiesMethodNameResolver
- リクエストURLとユーザ定義の値を比較して名前解決する。例えば「/index/welcome.html=doIt」と設定した場合、「/index.welcome.html」にリクエストが来たら「doIt()」メソッドが呼ばれる。このメソッド名解決はPathMatcherと一緒に動作するため「/**/welcom?.html」としてもちゃんと動作する。
サブクラスを作ってみる場合
ドキュメントに書いてなかったので作成中ですわ。
delegateパラメタを使う場合
DispatcherServletのBean定義ファイルには以下の記述をする。
<bean name="/testmultiactioncontroller.do"
class="org.springframework.web.servlet.mvc.multiaction.MultiActionController">
<property name="methodNameResolver" ref="paramResolver"/>
<property name="delegate" ref="testDelegate"/>
</bean>
<bean id="paramResolver"
class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="method"/>
</bean>
<bean id="testDelegate" class="com.daipresents.spring204.test.TestDelegate"/>
「/testmultiactioncontroller.do」が呼ばれたらMultiActionControlerが呼ばれ、methodNameResolverにparamResolverというIDで指定されたParameterMethodNameResplverが使われる。そして、委譲先にはtestDelegateというIDで指定されたTestDelegateが使われる。
続いてTestDelegateクラスには「testMethod」メソッドを用意する。
public class TestDelegate {
public ModelAndView testMethod(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("testMethodが呼ばれました。");
return new ModelAndView("/index.jsp");
}
}
そして、JSPから「ContextPath/testmultiactioncontroller.do?method=testMethod」にアクセスすると、methodパラメタで指定したtestMethodが呼ばれる。
今のところBean定義ファイルにName属性で指定しないとうまくいかない。「SimpleUrlHandlerMapping」なんか使えばうまくいくみたいだけど。。。
PropertiesMethodNameResolverを使ったらこんな書き方になる。(サンプルより)
<!-- Application specific multi-action controller -->
<bean id="countriesController" class="org.springframework.samples.countries.web.CountriesController">
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/home.htm">handleHome</prop>
<prop key="/config.htm">handleConfig</prop>
<prop key="/copy.htm">handleCopy</prop>
<prop key="/main/home.htm">handleMain</prop>
<prop key="/main/detail.htm">handleDetail</prop>
<prop key="/main/countries.xls">handleExcel</prop>
<prop key="/main/countries.pdf">handlePdf</prop>
</props>
</property>
</bean>
</property>
<property name="countryService" ref="countryService"/>
</bean>