Spring BootのRestControllerの@PathVariableと@RequestParamの使い方や@Validate,@Validでバリデーションチェックを行う方法

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」を付加した例です。

Spring BootのRestControllerの@PathVariableと@RequestParamの使い方

@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エラーとなります。

タイトルとURLをコピーしました