Spring Bootの@Validatedでリクエストパラメータのバリデーションを行う




バリデーション

Spring Bootではクライアントからのリクエストパラメータをアノテーションだけで簡単にバリデーションすることができます。

バリデーションとは送られてきた値がサーバが想定していたものか判定することを言います。例えばString型のパラメータでNULLは許容しないけど空文字は許容するなどの設定をアノテーションを使って簡単に行うことができます。

今回はバリデーションの設定方法を中心に紹介したいと思います。

リクエストパラメータを受け取るクラス

クライアントからのリクエストを専用のクラスを作成して受け取ります。このクラスでどんなパラメータを受け取るかバリデーションを設定します。

下記SampleRequestクラスではwordというパラメータを受け取ります。String型で@NotBlankを設定することでwordにはNULL、空文字列、スペースのみの文字列を受け取ることができ無くなります。

これがアノテーションによる設定です。非常に簡単ですね。

class SampleRequest {
    @NotBlank
    lateinit var word: String
}

コントローラ

リクエストを受け取るクラスにアノテーションを設定するだけではバリデーションは行えません。リクエストを受け取るコントローラにも設定を行います。

@Validatedアノテーションをバリデーションを有効化したい変数に対して設定するだけです。

@RestController
class SampleController @Autowired constructor(private val timelineFacade: TimelineFacade) {

   /**
     * @param SampleRequest サンプルリクエスト
     * @return word
     */
    @GetMapping("/sample")
    fun getTimelineSearchList(@ModelAttribute @Validated request: SampleRequest): String {
        return request.word
    }
}

実際にcurlでリクエストを投げるとwordパラメータが空文字でエラーになります。

$ curl localhost:8080/sample?word=""
{
	"timestamp":1522364910676,
	"status":400,"error":"Bad Request",
	"exception":"org.springframework.validation.BindException",
	"errors":[
		{
			"codes":["NotBlank.sampleRequest.word","NotBlank.word","NotBlank.java.lang.String","NotBlank"],
			"arguments":[{"codes":["sampleRequest.word","word"],"arguments":null,"defaultMessage":"word","code":"word"}],
			"defaultMessage":"may not be empty",
			"objectName":"sampleRequest",
			"field":"word",
			"rejectedValue":null,
			"bindingFailure":false,"code":"NotBlank"
		}
	],
	"message":"Validation failed for object='sampleRequest'. Error count: 1",
	"path":"/sample"
}

BindingResult

BindingResultを使うとコントローラ内でエラーを扱うことができます。BindingResultの@Controllerを使うサーバサイドレンダリングな実装をしている時に使うのがベターみたいです。例えばサーバサイドからリダイレクト処理を行ったりとかですね。

@RestController
class SampleController @Autowired constructor(private val timelineFacade: TimelineFacade) {

   /**
     * @param SampleRequest サンプルリクエスト
     * @return word
     */
    @GetMapping("/sample")
    fun getTimelineSearchList(@ModelAttribute @Validated request: SampleRequest, result: BindingResult): String {
        if (result.hasErrors) pringln(result)
        return request.word
    }
}

@RestControllerを使ってRESTfullなAPIを実装している場合のエラーハンドリングはExceptionHandler内で処理するのが一般的とのことです。ExeptionHandlerの実装は下記を参考にしてください。

関連記事:Spring Bootでエラーハンドラーを実装する

おすすめ書籍

Springの概要からインストール方法、各コア機能(Security, Sessionなど)の解説が体系的にまとめられています。2018年に出版されたばかりなので情報も新しいです。これからSpring Bootでアプリケーション開発をしたい方の最初に読む一冊としておすすめします。対象は初心者だけでなく上級者まで幅広く学べるので是非読んでみてください!

 

The following two tabs change content below.

髙妻智一

2013年CyberAgent新卒入社 スマホゲームを作る子会社に所属し、サーバーサイドのエンジニアを担当。2年目の終わりから新規子会社の立ち上げに参加し、サーバーサイドのエンジニアリーダーとしてサービースのリリースから運用までを担当。 2018年仮想通貨のスマホウォレットを提供するGinco Incにブロックチェーンエンジニアとして入社。






よく読まれている関連記事はこちら



コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です