본문 바로가기

스터디 기록/SpringBoot 심화 스터디

나만의 Exception 만들기 & 유효성검사와 AOP

CustomException을 직접 만들어보자

서버단에서 터지는 예외가 프론트단에게 그 모습 그대로 넘어가지 않도록 예쁘게 처리해줘야한다. 즉, 예외를 내가 직접 컨트롤할 수 있어야 한다. 

ex 패키지 밑에 CustomApiException 클래스를 생성 후 message를 받도록 한다. message에 우리가 커스텀해 생성할 오류 메시지가 들어갈것이다.

 

handler 패키지 밑에 CustomExceptionHandler 클래스를 생성 후 @RestControllerAdvice로 등록해주고, 위에서 만든 CustomApiException을 받도록한다.
그럼 내가 설정한 CustomApiException으로 오류 메시지를 예쁘게 핸들링할 수 있다.

 

실제로 처리한 에러가 터졌을 때 json 형태 msg가 잘 나오는 걸 볼 수 있다.

 

+) 참고로 핸들러 클래스에서 사용하는 ResponseDto 내부는 Dto 패키지 밑에 이렇게 설정해두었다. 

 

이를 응용하면 SecurityConfig에서 발생하는 Exception로 예쁘게 응답해줄 수 있다.

util 패키지 아래에 CustomResponseUtil 클래스를 생성하고 실패와 성공 시 응답을 각각 json으로 예쁘게 만들어준다.

성공 시 data에 응답을 넣어 반환하고, 실패 시에는 에러 메시지를 넣어서 반환한다.

 

실제 성공 케이스 만들기
실제 실패 케이스 만들기

 

@Valid와 BindingResult로 에러 처리하기

사용자로부터 정보를 받을 때, 적절한 제한을 둬야한다. 이 제한을 쉽게 관리할 수 있는 방법이있다.

RequestDto에 제약조건을 걸어주고, 컨트롤러에서 @Valid와 BindingResult를 사용하는 방법이다.

예를 들어 회원가입 시 username, password 등에 제한을 두고 싶으면 RequestDto에 원하는 조건을 건다.
그리고 Controller에서 해당 ReqDto앞에 @Valid 어노테이션을 붙여주면 자동으로 검증을 해준다. 제한이 어겨져 예외가 발생하면 BindingResult에 담는다.

 

BindingResult 검증 처리 로직은 아래서 AOP와 함께 더 설명하겠다. 

 

실제로 제한이 어겨졌을 경우 오류가 어떻게 던져지는지 보자. 

빈칸이 될 수 없게 설정해 둔 password가 빈칸일 경우, "비어 있을 수 없습니다" 라는 문구가 뜨게된다.

 

유효성 검사 정규 표현식 종류는 아주 다양하다. 필요할 때 문서를 참고해서 다양한 기능을 적용해보자. 

 

AOP란?

애플리케이션의 공통 관심사를 분리하여 모듈화하는 프로그래밍 기법이다. 주로 로깅, 트랜잭션 관리, 보안, 에러 처리와 같은 기능을 분리하여 깔끔하게 한곳에서 사용할 수 있다.

 

각 기능에 대해 설명해보겠다. 

- Pointcut : 실제로 Advice를 적용할 대상을 지정하는 필터이다. Advice를 적용하고 싶은 곳에 Pointcut으로 등록할 수 있다.

- Advice : JoinPoint에 적용될 실제 공통 기능 코드를 정의한 것이다. 

 

코드를 기반으로 예시를 설명해보자면, 먼저 body 데이터를 가진 postMapping, putMapping 작동 시 유효성 검사를 하는 검증 로직을 모든 프로젝트에 공통으로 정의하고 싶다.

그럼 CustomValidationAdvice 클래스에서 @Pointcut 어노테이션으로 @PostMapping과 @PutMapping 어노테이션에서 AOP를 사용한다고 정의해주면 해당 어노테이션 사용때마다 검증 로직을 실행한다.

@Pointcut으로 정의 후
에러 검증 로직 실행하기

 

이러면 중복되는 검증 로직을 쉽게 공통화 할 수 있다. 

실제로 @PostMapping 어노테이션을 사용하는 곳에서 BindingResult를 가지고 검증 처리를 진행한다.