SimpleFormControllerで指定可能なプロパティ
SimpleFormControllerで指定可能なプロパティを調べてみる。
まずは、階層関係
java.lang.Object + org.springframework.context.support.ApplicationObjectSupport + org.springframework.web.context.support.WebApplicationObjectSupport + org.springframework.web.servlet.support.WebContentGenerator + org.springframework.web.servlet.mvc.AbstractController + org.springframework.web.servlet.mvc.BaseCommandController + org.springframework.web.servlet.mvc.AbstractFormController + org.springframework.web.servlet.mvc.SimpleFormController
org.springframework.web.servlet.mvc.AbstractControllerから、コントローラで設定可能なプロパティがでてくる。
このクラスで指定可能なプロパティは、
- supportedMethods
- requireSession
- cacheSeconds
- synchronizeOnSession
サブクラスのorg.springframework.web.servlet.mvc.BaseCommandControllerでは、
- commandName
- commandClass
- validators
- validator
- validateOnBinding
さらに下がってorg.springframework.web.servlet.mvc.AbstractFormControllerでは、
- bindOnNewForm
- sessionForm
そして最後のSimpleFormControllerでは、
- formView
- successView
これらをまとめるとこんな感じでしょうか。
プロパティ名 | デフォルト値 | 詳細 | 指定可能なクラス |
---|---|---|---|
supportedMethods | GET,POST | サポートするHTTPメソッドをカンマ区切り(CSV形式)で指定 | AbstractController |
requireSession | false | リクエスト処理にセッションが必要かどうか | AbstractController |
cacheSeconds | -1 | キャッシュの有効期間を秒単位で指定(0指定時:no-cache -1指定時:キャッシュヘッダなし | AbstractController |
synchronizeOnSession | false | 同一セッションでのリクエストをシリアライズするか | AbstractController |
commandName | command | コマンド名 | BaseCommandController |
commandClass | null | コマンドオブジェクトとして利用するクラス名 | BaseCommandController |
validators | null | バリデータを配列で指定 | BaseCommandController |
validator | null | バリデータ名 | BaseCommandController |
validateOnBinding | true | リクエストパラメータをコマンドオブジェクトにバインドした後にバリデータを実行するか | BaseCommandController |
bindOnNewForm | false | 新規フォーム作成時(表示時)もリクエストパラメータを保存したままにするか | AbstractFormController |
sessionForm | false | フォームの値をセッション内で保存するか | AbstractFormController |
formView | null | フォーム入力画面 or validationチェック失敗時に表示する画面 | SimpleFormController |
successView | null | formViewで指定した画面でのsubmitが成功した場合に表示する画面 | SimpleFormController |
いまいちわかっていないプロパティもあるけど、その辺はいじり倒しながら確認するか。
SpringMVCとかServlet周りのメモ
Servletのライフサイクル
- サーブレットロード時(初回リクエスト時)にコンテナからinit()が呼び出される。
- リクエスト単位でservice()がコンテナから呼び出され、service()はリクエストの種別(GETとかPOST)に応じてdoXXX()を呼び出す。
- サーブレットのアンロード時にdestory()が呼び出される。
一応動作確認
package com.sample; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletTest extends HttpServlet { public ServletTest() { } public void init(ServletConfig config) throws ServletException { System.out.println("init()が呼び出されました"); } public void destroy() { System.out.println("destory()が呼び出されました"); } protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("service()が呼び出されました"); super.service(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doGet()が呼び出されました"); } }
SpringMVCでの処理順序
まずはorg.springframework.web.servlet.DispatcherServletからみてみる。
このクラスにはinit()/service()の両方が実装されてないので、親クラスをたどってみる。
階層関係はこんな感じ
java.lang.Object +- javax.servlet.GenericServlet +- javax.servlet.http.HttpServlet +- org.springframework.web.servlet.HttpServletBean +- org.springframework.web.servlet.FrameworkServlet +- org.springframework.web.servlet.DispatcherServlet
org.springframework.web.servlet.HttpServletBeanでfinal宣言された init() を見つけたので処理内容の確認。やってることは
- Beanプロパティの設定
- initServletBean()の呼び出し
の二つ。
initServletBean()の実装はこのクラスにはなく、サブクラスのFrameworkServletで行っている。こいつの処理内容は・・・
try { this.webApplicationContext = initWebApplicationContext(); initFrameworkServlet(); }
initFrameworkServlet()については、サブクラスのほうにも処理の実体は存在しないので、カスタムのDispatcherを作った時に使うのかな?initWebApplicationContext()では
- WebApplicationContextの生成
- onRefresh()の呼び出し
などをやっている様子。
onRefresh()はDispatcherServletで処理が実装されていて、initStrategies()を呼び出す。
initStrategies()の処理は、
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
となっていて、ようやくResolverとかの見慣れたものが出てきました。
あとは、ApplicationContext周りの処理を勉強すればこの辺の流れはすっきり確認できそう。
続いて、service()が同処理されるか。
これは、FrameworkServlet内でdoXXXメソッドがprocessRequest()を呼び出すように処理されていて、このメソッド内で
- doService()の呼び出し
- webApplicationContext.publishEventの実行
を行っている。
doService()はDispatcherServlet内で実装されていて、さらにdoDispatch()を呼び出す仕組みとなっている。
処理の詳細はいまいちわかっていないが、全体像はぼんやりつかめた感じ