본문 바로가기

끄적끄적

[Spring Boot] Interceptor - postHandle()

SpringBoot Interceptor

유저의 접근 경로에 따라 방문자수를 증가시켜야하는 기능을 구현해야했는데, 내가 생각한 선택사항은 크게 두가지였다.

 

1. 방문자수 증가 로직이 필요한 객체마다 해당 기능을 구현한 객체를 참조하게 한다.

2. 인터셉터를 하나 두어 방문자수 증가 로직이 필요한 경우 인터셉터가 작동하게 한다.

 

나는 2번을 선택했는데, 그 이유는, 인터셉터를 이용할경우, 객체간의 의존성을 크게 줄일 수 있을것이라고, URL을 참조해서 방문자 수를 증가시켜야 하기에, 인터셉터 발동 조건을 URL별로 설정할수있는 인터셉터가 최적일 것 이라고 생각했다.

 

어쨌든 위와 같은 때문에 Interceptor에 해당 기능을 구현하기로 했는데, 문제되는 상황은 다음과 같았다.

- 비즈니스 로직에서 예외를 반환하면 방문자 수를 증가시키면 안됨.

preHandle()의 경우 preHandle에서 false를 반환하면 실행하지않는다. 하지만 내 상황은 로직에 따라서, 방문자 수를 증가시켜야 하기때문에, postHandle()에 기능을 구현해야했다.

 

알아볼것은 "비즈니스 계층에서 예외를 반환한경우, postHadle()이 실행 되는가??"로 간단하다. 

(내가 원하는 상황은 실행되면 안된다.)

만약 이게 안되면, HttpResponse의 body를 참조해서 예외상황인지 확인하는방식으로 구현해야해서 복잡하고 귀찮아진다.

 

우선, springdocs에 정의된 postHandle()의 를 읽어보면,

 

출처 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/HandlerInterceptor.html

 

첫번째 줄에 handler가 성공적으로 실행된 후, Interception한다고 적혀있다. 과연, 내가 원하는것 처럼 동작할지 테스트 해보자.

interceptor를 간단하게 만들고 등록해주자

(등록하는 설정 코드는 생략하겠음)

.addTotalVisitors(name)과 addVisitorStatistics(name)이 실제 방문자 증가 구현 로직이다.

 

Transaction을 인터셉터 계층에서 부터 해놓은 이유는, 서로 다른 Service객체가 JPA의 1차캐시를 공통으로 사용하게 하기 위해서인데, Transaction을 하위 계층으로 내리는것과 저렇게 해놓는것중 뭐가 더 좋은것인지는 아직 잘 모르겠다..

 

우선 postman으로 잘 동작하는지 확인해보자.

(지속해서 테스트할 필요없이, 한번만 테스트하면 되는것이라, 번거롭게 테스트 코드 작성하는거 보다 로그찍어보거나 postman으로 테스트 하는게 더 효율적 일것이다)

 

테스트 결과

interceptor발동 path를 3번 호출했더니, 방문자수 또한 3으로 증가했다. 잘 증가하는걸 볼수있음

 

인터셉터 호출시 로그가 찍히게 설정하고 DB에 저장되어있지 않은 유저를 호출해보자.

이때, 인터셉터 로그가 찍히면 실패다.

 

호출 결과

의도한대로 없는 유저호출이 되었다. 이제, 인터셉터에 설정한 로그가 찍혔나 확인해보자.

 

깔끔한 콘솔창!

로그가 찍히지 않는것으로 보아 postHandle()메소드는 비즈니스 로직이 "성공적"으로 실행된 경우에만 실행되는것으로 보인다.