環境
- Spring boot 3.2.4
- Amazon Corretto JDK 17
調査したこと
- Controllerで日付のパラメタを受け取るときに、バリデーションをかけたい
- @DateTimeFormatと@JsonFormatは@Sizeなどの通常のバリデーションとスローされる例外が異なっていた
- @RequestParamと@RequestBodyの位置の違いでも動作が異なるため、それぞれ試してみる
結果
位置 | バリデーション | スローされる例外 |
---|---|---|
@PathVariable | @Size | ConstraintViolationException |
@PathVariable | @DateTimeFormat | MethodArgumentTypeMismatchException |
@RequestParam | @Size | ConstraintViolationException |
@RequestParam | @DateTimeFormat | MethodArgumentTypeMismatchException |
@RequestBody | @Size | MethodArgumentNotValidException |
@RequestBody | @JsonFormat | HttpMessageNotReadableException |
検証する
検証用のコード
SandboxController.java
@RestController
@Validated
public class SandboxController {
@PostMapping("/echo/{pathText}/{pathTime}")
public ResponseEntity<EchoResponse> postEcho(
@PathVariable(name = "pathText") @Size(min = 1, max = 10) String pathText,
@PathVariable(name = "pathTime") @DateTimeFormat(pattern = "yyyy-MM-dd_HH:mm:ss") LocalDateTime pathTime,
@RequestParam(name = "paramText") @Size(min = 1, max = 10) String paramText,
@RequestParam(name = "paramTime") @DateTimeFormat(pattern = "yyyy-MM-dd_HH:mm:ss") LocalDateTime paramTime,
@RequestBody @Validated EchoRequest request
){
EchoResponse res = new EchoResponse(paramText, paramTime);
return new ResponseEntity<EchoResponse>(res, HttpStatus.OK);
}
}
EchoRequest.java
@Getter
public class EchoRequest {
@Size(min = 1, max = 10)
String bodyText;
//Bodyでは@DateTimeFormatが効かないので、@JsonFormatを使用する
//@DateTimeFormat(pattern = "yyyy-MM-dd_HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd_HH:mm:ss")
LocalDateTime bodyTime;
}
EchoResponse.java
@Getter
@Setter
@AllArgsConstructor
public class EchoResponse {
String text;
LocalDateTime time;
}
ControllerExceptionHandler.java
@RestControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleAnyException(Exception e){
e.printStackTrace();
String reason = e.getClass().toString();
return new ResponseEntity<>(reason, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
パターンに一致する場合
{
"text": "1234567890",
"time": "2024-12-31T00:00:00"
}
@PathVariableの@Sizeが通過できなかった場合
- ConstraintViolationException がスローされた
POST /echo/12345678901/2024-12-31_00:00:00?paramText=1234567890¶mTime=2024-12-31_00:00:00 HTTP/1.1
{
"bodyText": "1234567890",
"bodyTime": "2024-12-31_00:00:00"
}
HTTP/1.1 500 Internal Server Error
class jakarta.validation.ConstraintViolationException
@PathVariableの@DateTimeFormatが通過できなかった場合
- MethodArgumentTypeMismatchException がスローされた
POST /echo/1234567890/2024-12-31_00:00:0000?paramText=1234567890¶mTime=2024-12-31_00:00:00 HTTP/1.1
{
"bodyText": "1234567890",
"bodyTime": "2024-12-31_00:00:00"
}
HTTP/1.1 500 Internal Server Error
class org.springframework.web.method.annotation.MethodArgumentTypeMismatchException
@RequestParamの@Sizeが通過できなかった場合
- ConstraintViolationException がスローされた
POST /echo/1234567890/2024-12-31_00:00:00?paramText=12345678901¶mTime=2024-12-31_00:00:00 HTTP/1.1
{
"bodyText": "1234567890",
"bodyTime": "2024-12-31_00:00:00"
}
HTTP/1.1 500 Internal Server Error
class jakarta.validation.ConstraintViolationException
@RequestParamの@DateTimeFormatが通過できなかった場合
- MethodArgumentTypeMismatchException がスローされた
POST /echo/1234567890/2024-12-31_00:00:00?paramText=1234567890¶mTime=2024-12-31_00:00:0000 HTTP/1.1
{
"bodyText": "1234567890",
"bodyTime": "2024-12-31_00:00:00"
}
HTTP/1.1 500 Internal Server Error
class org.springframework.web.method.annotation.MethodArgumentTypeMismatchException
@RequestBodyの@Sizeが通過できなかった場合
- MethodArgumentNotValidException がスローされた
POST /echo/1234567890/2024-12-31_00:00:00?paramText=1234567890¶mTime=2024-12-31_00:00:00 HTTP/1.1
{
"bodyText": "12345678901",
"bodyTime": "2024-12-31_00:00:00"
}
HTTP/1.1 500 Internal Server Error
class org.springframework.web.bind.MethodArgumentNotValidException
@RequestBodyの@DateTimeFormatが通過できなかった場合
- HttpMessageNotReadableException がスローされた
POST /echo/1234567890/2024-12-31_00:00:00?paramText=1234567890¶mTime=2024-12-31_00:00:00 HTTP/1.1
{
"bodyText": "1234567890",
"bodyTime": "2024-12-31_00:00:0000"
}
HTTP/1.1 500 Internal Server Error
class org.springframework.http.converter.HttpMessageNotReadableException