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(ES20xx),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^

