M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

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オブジェクトのプロパティとして集約して受け取る)が利用できるようになる。