[Spring] RestControllerAdvice를 이용한 Validation처리
들어가기 전
RestControllerAdvice가 무엇인지에 대해 먼저 알아보고 RestControllerAdvice을 활용한 Validation처리 방법에 대해 알아보겠습니다.
validation을 하기 위한 설정
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-validation'
- 의존성을 추가하면 @Valid를 이용하여 Validation처리를 할 수 있습니다.
@RestControllerAdvice이란?
@ExceptionHandler, @ModelAttribute, @InitBinder가 적용된 메서드들에 AOP를 적용해 Controller단에 적용하기 위하 고안된 어노테이션입니다.
클래스에 선언하면 되고 @RestController에 대한 전역적으로 발생하는 예외를 처리할 수 있습니다.
그리고 RestControllerAdvice를 보면 ControllerAdvice + ResponseBody가 있습니다.
ControllerAdvice는 RestControllerAdvice와 동일한 역할을 수행합니다.
하지만 ControllerAdvice는 단순히 예외만 처리하고 싶을 때 사용하고 RestControllerAdvice는 예외를 응답할 때 객체로 리턴해야 할 때 사용합니다.
@RestControllerAdvice 사용 전 Validation처리
필자는 Validation을 처리할 때 아래와 같이 하면 처리된다고 생각을 했습니다.
@AllArgsConstructor
@Getter
@NoArgsConstructor
public class PersonRequestDto {
@NotBlank
private String name;
@NotNull
private String address;
}
@RestController
public class RestControllerAdviceExampleController {
@PostMapping
public void exampleValidation(@Valid @RequestBody PersonRequestDto personRequestDto) {
}
}
필자가 생각한 결과
실제 결과
필자가 작성한 코드처럼 했는데 위의 사진처럼 validation처리가 안되었을 경우 MethodArgumentNotValidException이 발생을 했는지 Console에서 확인을 합니다.
이거에 대한 해결방법은 바로 아래에서 설명하겠습니다.
해결방법
@RestController
public class RestControllerAdviceExampleController {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> exampleResponseValidation(MethodArgumentNotValidException e) {
Map<String, String> error = new HashMap<>();
e.getAllErrors().forEach(
c -> error.put(((FieldError) c).getField(), c.getDefaultMessage())
);
return ResponseEntity.badRequest().body(error);
}
@PostMapping
public void exampleValidation(@Valid @RequestBody PersonRequestDto personRequestDto) {
}
}
- 해당 컨트롤러에서 MethodArgumentNotValidException가 발생하면 @ExceptionHanlder로 처리합니다.
이렇게 해서 문제는 해결할 수 있습니다. 하지만 치명적인 단점이 있습니다. 컨트롤러에 @ExceptionHanlder를 사용하여 validation처리할 때 컨트롤러를 생성할 때마다 @ExceptionHanlder를 사용하여 validation을 처리하는 코드를 작성을 해줘야 됩니다.
그럼 불필요하게 중복적인 코드가 발생하게 됩니다.
중복적인 코드가 발생하는 것을 방지하기 위해 @RestControllerAdvice 또는 @ControllerAdvice를 사용하여 전역적으로 처리해 주면 됩니다.
@RestControllerAdvice를 사용하여 전역적으로 Validation을 처리하는 방법
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class ExampleRestControllerAdvice {
}
- @RestControllerAdvice를 클래스에 붙여줍니다. ControllerAdvice를 사용해야 되는 경우라면 @ControllerAdvice를 붙여주면 됩니다.
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class ExampleRestControllerAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> exampleResponseValidation(MethodArgumentNotValidException e) {
Map<String, String> error = new HashMap<>();
e.getAllErrors().forEach(
c -> error.put(((FieldError) c).getField(), c.getDefaultMessage())
);
return ResponseEntity.badRequest().body(error);
}
}
위와 같이 코드를 작성하고 결과를 확인하면 원했던 결과가 확인할 수 있습니다.
'Spring Boot' 카테고리의 다른 글
[Spring] 스프링 AOP와 프록시 패턴 (1) | 2023.07.03 |
---|---|
[Spring] WebClient를 이용한 Naver Papago 번역 연동 (0) | 2023.03.07 |
[Spring Boot] @ModelAttribute + 객체값 Null일때 해결방법 (2) | 2022.10.25 |
[Spring Boot] JUnit5에서 @RequiredArgsConstructor (0) | 2022.04.22 |
[Spring] 예외처리와 오류 페이지 (0) | 2022.01.04 |
댓글
이 글 공유하기
다른 글
-
[Spring] 스프링 AOP와 프록시 패턴
[Spring] 스프링 AOP와 프록시 패턴
2023.07.03 -
[Spring] WebClient를 이용한 Naver Papago 번역 연동
[Spring] WebClient를 이용한 Naver Papago 번역 연동
2023.03.07 -
[Spring Boot] @ModelAttribute + 객체값 Null일때 해결방법
[Spring Boot] @ModelAttribute + 객체값 Null일때 해결방법
2022.10.25 -
[Spring Boot] JUnit5에서 @RequiredArgsConstructor
[Spring Boot] JUnit5에서 @RequiredArgsConstructor
2022.04.22