Spring Web MVCのコントローラで任意の型のパラメータを受け取る
久しぶりにSpring Web MVCについて調べてみた。タイトルの通り、やりたいことは「Spring Web MVCのコントローラで任意の型のパラメータを受け取る」ということ。サンプルコードは公式リファレンスのセクション"Customizing WebDataBinder initialization"にもある。
Spring Web MVCではコントローラ・クラス(@Controller
アノテーションが付与されたクラス)のメソッドで、文字列だけでなく数値・真偽値などのパラメータを取ることができる。これらのパラメータには、HTTPリクエストのクエリ文字列やリクエスト本文の内容をフレームワークが変換した結果の値が設定される。クエリ文字列由来の値であれば以下のように:
@Controller public class FooController { @RequestMapping(value = "/foo-list", method = RequestMethod.GET) public List<Foo> get(@RequestParam("id") final int id, @RequestParam("name") final String name) { // idやnameにはクエリ文字列から採取され変換された値が設定される // そしてここで何かしらの処理 } }
このパラメータの型として任意の型を指定したい場合、PropertyEditor
インターフェースの実装を使用する。このインターフェースには PropertyEditorSupport
というデフォルト実装が用意されているのでこれを利用するのがお手軽:
public class FooEditor extends PropertyEditorSupport { @Override public String getAsText() { final Object o = getValue(); // ここでoはこのEditorが編集対象とする型のオブジェクト // その内容をもとにして文字列表現を構築して呼び出し側に返す return ...; } @Override public void setAsText(String s) { // ここで文字列をパースしてこのEditorが編集対象とするオブジェクトを初期化 final Object o = ...; // それをsetValue(Object)メソッドでEditorのフィールドに格納 setValue(o); } }
このPropertyEditor
をSpring Web MVCに認識させ、実際のパラメータの型変換に利用させるには2つの方法がある。1つはコントローラごとに@InitBinder
アノテーションを持つメソッドを用意する方法:
@InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Foo.class, new ForEditor()); }
もう1つは WebBindingInitializer
というインターフェースの実装を使用するものだけど、公式リファレンスではその設定方法がいまいちよくわからない。XML形式での設定方法はサンプルもあるのだけど、Javaコードでコンフィギュレーションする方法がわからない。今回は1つめの方法で十分なので調査はいったんここまでにした。
いずれにしてもWebDataBinder
を使って、カスタムメイドのPropertyEditor
とそれが編集対象とするオブジェクトの型を指定する。これで任意の型のパラメータについて、@RequestParam
(クエリ文字列の1項目をメソッド引数の1つとして受け取る)やModelAttribute
(クエリ文字列の複数項目をメソッド引数のJavaBeansオブジェクトのプロパティとして集約して受け取る)が利用できるようになる。