Spring BootのRestControllerの@PathVariableと@RequestParamの使い方
Spring BootでRest APIを作成するときにGETリクエストの場合、@PathVariableと@RequestParamを使うと思いますが、使い分けがわかりづらいので整理しておきます。
@PathVariable
Rest形式のurlに{age}というように含む場合は、@PathVariableを使用します。
@GetMapping(value = "/getMethod/{age}") public Long get(@PathVariable("age") Long age) { return age; }
@GetMappingアノテーションで指定するurlのうち、{age}で指定したものを@PathVariable(“age”)で取得して返却しています。
@RequestParam
Rest形式のurlに、「?a=1」というようにクエリ文字列を付加して、その値を取得する場合に@RequestParamを使用します。
@GetMapping(value = "/getMethod") public Long get(@RequestParam("age") Long age) { return age; }
@GetMappingアノテーションで指定するurlに対して「?age=25」を付加した例です。
@PathVariableに日時(LocalDate)を使用する方法
@PathVariableにLocalDateを指定する場合は@DateTimeFormatをセットで使用する必要があります。
以下のように記述することでURLに日付を指定することができます。
例)http://xxx/getXX/20190101
getXX(@DateTimeFormat(pattern="yyyyMMdd" @PathVariable LocalDate targetDate) { // 〜何らかの処理 }
パスパラメータ | リクエストパラム |
---|---|
/getMethod/1/2 | ?id=1&age=2 |
@Validated,@Validでパスパラメータやリクエストパラメータのチェックをする
リクエストパラメータのバリデーションチェックを行う方法です。
build.gradleに依存関係を追加します。この依存関係がないとバリデーションは実行されません。
implementation "org.springframework.boot:spring-boot-starter-validation:2.3.2.RELEASE"
クラスに@Validatedアノテーションを付与します。
@RequestParamの前に@Validを付与します。
package jp.co.confrage.presentation.controller; import javax.validation.Valid; import javax.validation.constraints.Pattern; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Validated @RestController public class ValidationController { @RequestMapping( path = "/valids", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<?> valids( @RequestHeader HttpHeaders headers, @Valid @Min(1) @Max(100) @RequestParam(name = "empId") final Integer empId) throws Exception { return new ResponseEntity<>("", headers, HttpStatus.OK); } }
1以上100以下の場合、エラーとします。エラーハンドリングは新規でクラスを作成します。
ConstraintViolationExceptionが発生するので、第一引数にConstraintViolationExceptionを指定します。
package jp.co.confrage.infrastructure.exception; import javax.validation.ConstraintViolationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @RestControllerAdvice public class RestExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler public ResponseEntity<?> handleConstraintViolationException( ConstraintViolationException ex, WebRequest request) { return super.handleExceptionInternal(ex, "", null, HttpStatus.BAD_REQUEST, request); } }
これでクエリパラメータがja,en以外の場合は例外をハンドリングするクラスに遷移して、BAD_REQUEST(400エラー)となります。
AOPを使用していると、ハンドリングが上手く動作しませんので注意です。
@Patternでnullを許容する
バリデーションチェックをすると、パラメータがnullだった場合にbad requestになってしまいます。
バリデーションチェックやパターンチェックをしながらnullを許容するには、Optionalクラスでラップしてあげます。
@RequestParamのrequired属性をfalseにしてあげれば、クエリパラメータが未指定でも400エラーとはなりません。
@Pattern(regexp = "(ja|en)") @RequestParam(name = "lang", required = false)
この属性を省略した場合はtrueとなり、400エラーとなります。
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^