티스토리 뷰
Validation 객체를 통해 데이터 유효성 검증을 진행해야하는데,
javax.validation.Valid 와
org.springframework.validation.annotation.Validated 간의 차이점을 알게되어 짧게 글을 남긴다.
** 검증할 객체
public class BoardAdd {
@NotBlank
private String title;
//@NotBlank(message = "{validation.board.test}") // messageSource 에 접근 가능
@NotBlank
private String content;
private String name;
private String pwd;
// Getter, Setter
}
1. @Valid
- Java 에서 지원하는 표준 검증
- Spring에선 Controller 진입시 Model 을 맵핑하는 과정에서 Annotation 을 감지, 검증을 진행하게 된다.
- 검증 실패시 MethodArgumentNotValidException 을 Throw 한다.
@PostMapping(value = {""})
public ResponseEntity<BoardVO> boardAdd(
@RequestBody @Valid BoardAdd boardApp,
@AuthenticationPrincipal OAuth2UserPrincipal oAuth2UserPrincipal
) {
Long seqUser;
if (oAuth2UserPrincipal != null) {
seqUser = oAuth2UserPrincipal.getSeqUser();
} else {
seqUser = null;
}
return ResponseEntity.ok(boardManager.addBoard(boardApp, seqUser));
}
...
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>> handleValid(MethodArgumentNotValidException e) {
logger.error("handleValid");
BindingResult bindingResult = e.getBindingResult();
ErrorResp errorResp = ErrorResp.getBadRequest();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
errorResp.addError(fieldError.getObjectName(), fieldError.getRejectedValue(), fieldError.getDefaultMessage());
}
return ResponseEntity.status(errorResp.getStatus()).body(errorResp.toData());
}
2. @Validated
- Spring 에서 @Valid 를 감싼 검증 방식
- Spring에선 AOP 방식으로 요청을 가로채서 검증하기때문에 Controller 외의 모든 Bean 에서 검증이 진행된다.
- 검증 실패시 ConstraintViolationException 을 Throw 한다.
@PostMapping(value = {""})
public ResponseEntity<BoardVO> boardAdd(
@RequestBody @Validated BoardAdd boardApp,
BindingResult bindingResult,
@AuthenticationPrincipal OAuth2UserPrincipal oAuth2UserPrincipal
) {
if (bindingResult.hasFieldErrors()) {
ErrorResp errorResp = ErrorResp.getBadRequest();
for (FieldError fieldError: bindingResult.getFieldErrors()) {
errorResp.addError(fieldError.getObjectName(), fieldError.getRejectedValue(), fieldError.getDefaultMessage());
}
throw errorResp;
}
Long seqUser;
if (oAuth2UserPrincipal != null) {
seqUser = oAuth2UserPrincipal.getSeqUser();
} else {
seqUser = null;
}
return ResponseEntity.ok(boardManager.addBoard(boardApp, seqUser));
}
( 단, 여기서 내가 사용한 방식이 좀 달랐던거 같은데,
일반적으론 class 에다가 @Validated를 선언하고, 멤버변수에는 @Valid 를 선언한뒤,
ConstraintViolationException 을 캐치하는 방식을 사용한다고 한다.
그러면 결국 위의 1번 방식과 동일하게 Exception Handling 이 가능해진다. )
** ConstraintViolationException Handler
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Map<String, Object>> handleValidated(ConstraintViolationException e) {
logger.error("handleValidated");
ErrorResp errorResp = ErrorResp.getBadRequest();
for (ConstraintViolation<?> constraintViolation : e.getConstraintViolations()) {
errorResp.addError(constraintViolation.getPropertyPath().toString(), constraintViolation.getInvalidValue(), constraintViolation.getMessage());
}
return ResponseEntity.status(errorResp.getStatus()).body(errorResp.toData());
}
Spring 이니까 @Validated 를 사용하는 방향으로 잡아야 할것 같은데,
당장에 Controller 외의 다른 부분에서 검증을 진행할 계획은 없기때문에 @Valid 를 사용하기로 한다.
'Back-End Framework > SpringBoot' 카테고리의 다른 글
(실패, 뻘짓) 실행전에 @Service bean 변경하기 feat. BeanFactoryPostProcessor (0) | 2023.07.05 |
---|---|
@Transactional 과 flush (0) | 2023.03.09 |
Service와 ServiceImpl 에 대해 (0) | 2023.03.06 |
SPA 구성 - Specification 과 SpecificationBuilder (0) | 2023.02.18 |
SPA 구성 - JPA Repository 와 Specification (0) | 2022.06.03 |
- Total
- Today
- Yesterday
- github-actions
- Hunua Falls
- @Profile
- springboot
- Cosseys Dam
- JPA
- istio
- Specification
- docker
- kubernetes
- Cloud SQL
- Waitawa Regional Park
- pinia
- BeanFactoryPostProcessor
- Browns Bay
- jquery
- Spring
- vue3
- nodejs
- BannSang Korean
- Spring Cloud Config
- auditing
- Pinehill
- GCP
- Murrays Bay
- k8s
- EnvironmentAware
- AWS
- express
- @Validated
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |