谷本 心 in せろ部屋

はてなダイアリーから引っ越してきました

Spring MVCのOptional<>の使い方がカッコイイ。

Spring Bootの1.2.0正式版がリリースされ、中で使っているSpringも4.0から4.1になりました。
SpringMVCも4.1になったわけですが、一つ興味深い変更がありました。
それが@RequestParamのOptional対応です。


SprinMVCでは、クエリ文字列の値をメソッドの引数にバインドするための
@RequestParamアノテーションは、何も書かないと「必須項目」と見なされてしまいます。

@RestController
public class HelloController {
    @RequestMapping("/")
    public String hello(@RequestParam("name") String name) {
        if (name != null) {
            return "Hello, " + name;
        } else {
            return "Hello, John";
        }
    }
}

こんなコントローラーを書いてSpring Bootを起動し、
localhost:8080/ にアクセスすると、エラーが発生します。

There was an unexpected error (type=Bad Request, status=400).
Required String parameter 'name' is not present

nameが指定されていないというエラーです。
デフォルトで必須になるというのは、僕の直感と違っています。


必須にしないために、Spring MVC 4.0までは
わざわざ必須でないことを宣言しなくてはいけませんでした。

@RestController
public class HelloController {
    @RequestMapping("/")
    public String hello(@RequestParam(value = "name", required = false) String name) {
        if (name != null) {
            return "Hello, " + name;
        } else {
            return "Hello, John";
        }
    }
}

これなら、別に値を指定しなくとも怒られません。

Hello, John

でも、繰り返しになりますが、これは僕の直感と違っています。
クエリ文字列なんて、必須ではない任意項目でしょう。


ここで、Spring MVC 4.1ではOptionalが使えるようになりました。

@RestController
public class HelloController {
    @RequestMapping("/")
    public String hello(@RequestParam("name") Optional<String> name) {
        if (name.isPresent()) {
            return "Hello, " + name.get();
        } else {
            return "Hello, John";
        }
    }
}

コードの見た目もすっきりしますし、
これこそOptionalの適材適所な使い方という感じでクソカッコイイですね。


OptionalのGood exampleだと思います。勉強になるなぁ。