도메인이나 Dto를 구성하는 필드의 유효성 검사를 해주는 데이터 유효성 검사 표준 기술인 Bean Validation은 반복되는 유효성 검사를 간단하게 할 수 있게 하는 기능이다.
@NotNull
값이 비어있지 않는 제약
@Positive
값이 양수인 제약
@PositiveOrZero
값이 양수이거나 0인 제약
@Min(value=최소값)
값의 최소값 제약
@Max(value=최대값)
값의 최대값 제약
@NotBlank
collection의 대한 제약으로 최소 1개 이상의 값이 들어야 있어야 되는 제약
@NotEmpty
값에 대한 공백 제약
@Length(min, max)
값이 가지는 길이 제약
@Getter
@AllArgsConstructor
public class CreateProductDto {
@NotBlank
private String name;
private String genre;
//메세지를 통해 에러에 대한 정보를 제공할 수 있다.
@Positive(message = "Quantity should be positive")
private Long quantity;
@Positive(message = "Price should be positive")
private Long price;
private String img;
}
컨트롤러에서 위에서 정의한 유효성 검사가 실제로 진행되기 위해서는 검증을 하는 변수에 대해 @Valid를 표시해야 한다.
@RestController
@RequestMapping("/api/v1/products")
public class ProductController {
@PostMapping(value = "",consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
//dto에 지정한 제약 조건에 대한 검증을 수행한다.
public String createProduct(@RequestBody @Valid CreateProductDto createProductDto) {
productService.createProduct(createProductDto.getName(), createProductDto.getGenre(), createProductDto.getQuantity(), createProductDto.getPrice(), createProductDto.getImg());
return "Successfully create product";
}
}
@Valid의 경우 컨트롤러 단에서 검증을 하게 되어 서비스나 레포지터리 단에서 유효성 검증을 하게 되는 경우 빈에 붙여야 되는 아노테이션으로 aop를 사용해서 유효성 검증을 제공하고 있다. 또한 속성 제약조건에 대한 그룹을 만들어 적용시킬 수 있다.
유효성 검증에서 통과하지 못한 경우 발생되는 MethodArgumentNotValidException을 ExceptionHandler를 통해 catch를 하여 에러 메세지에 대한 내용을 응답으로 확인할 수 있다.
@RestControllerAdvice
public class ControllerAdvice {
//유효성 검증이 실패한 경우 발생하는 exception
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity handleValidException(MethodArgumentNotValidException exception) {
//제약 조건 내 개발자가 기록한 message를 가져온다.
String errorMessage = exception.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(errorMessage);
}
}