이전 글에서는 애플리케이션에 로그백(Logback)을 적용해서, 특정 기능이 실행되었을 때 IDE 콘솔에 SQL 쿼리 로그를 출력하는 방법을 알아보았습니다.
이번에는 스프링에서 제공해주는 기능 중 하나인 인터셉터(Interceptor)를 적용해 보도록 하겠습니다.
1. 인터셉터(Interceptor)란?
인터셉터는 이름 그대로 "무언가를 가로챈다."라는 의미를 가집니다. 인터셉터는 컨트롤러의 메서드(URI)에 접근하는 과정에서 무언가를 제어할 필요가 있을 때 사용됩니다.
정확히는 컨트롤러에 접근하기 전과 후로 나뉘는데요. 예를 들어 회원제 시스템과 같은 경우, 로그인 또는 계정의 권한과 관련된 로직을 인터셉터를 이용해서 더욱 효율적으로 처리할 수 있습니다.
2. HandlerInterceptor를 이용해서 인터셉터 구현하기
인터셉터는 HandlerInterceptor 인터페이스를 implements 해서 구현할 수 있습니다. 해당 인터페이스는 preHandle( ), postHandle( ), afterCompletion( ) 총 세 개의 추상 메서드를 포함하고 있는데요. 우리는 preHandle( )과 postHandle( ) 두 개의 메서드만 구현합니다.
가장 먼저, LoggerInterceptor 클래스를 추가한 후 코드를 작성해 주시면 되는데요. 인터페이스를 implements 한 후에 해당 클래스에서 (마우스 우클릭 - Generate - Implement Methods) 또는 Alt + Shift + P를 누르면, 구현할 메서드를 추가할 수 있습니다.
package com.study.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class LoggerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("===============================================");
log.debug("==================== BEGIN ====================");
log.debug("Request URI ===> " + request.getRequestURI());
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.debug("==================== END ======================");
log.debug("===============================================");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
}
기능 | 설명 |
@Slf4j | 롬복(Lombok)에서 제공해주는 어노테이션으로, 로깅 추상화 라이브러리입니다. 로깅 추상화란, 로깅을 직접 하지 않고 로깅 구현체를 찾아 기능을 사용할 수 있게 해주는 것을 의미합니다. |
preHandle( ) | 컨트롤러의 메서드에 매핑된 특정 URI가 호출됐을 때 실행되는 메서드로, 컨트롤러를 경유(접근)하기 직전에 실행되는 메서드입니다. 우리는 사용자가 어떠한 기능을 수행했는지 파악하기 위해, 해당 메서드(기능)와 매핑된 URI 정보가 로그로 출력되도록 처리합니다. |
postHandle( ) | 컨트롤러를 경유(접근) 한 후, 즉 화면(View)으로 결과를 전달하기 전에 실행되는 메서드입니다. preHandle( )과는 반대로 요청(Request)의 끝을 알리는 로그가 콘솔에 출력되도록 처리합니다. |
3. WebMvcConfigurer 인터페이스 구현하기
이제 LoggerInterceptor 클래스가 작동할 수 있도록 클래스를 빈(Bean)으로 등록해 주어야 하는데요. 이를 위해 WebMvcConfigurer 인터페이스를 구현한 설정 클래스가 필요합니다. WebMvcConfig 클래스를 추가한 후 코드를 작성해 주세요.
package com.study.config;
import com.study.interceptor.LoggerInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggerInterceptor())
.excludePathPatterns("/css/**", "/images/**", "/js/**");
}
}
WebMvcConfigurer | 해당 인터페이스를 구현하면 @EnableWebMvc의 자동 설정을 베이스로 가져가며, 개발자가 원하는 설정까지 추가할 수 있다는 장점이 있습니다. (Override 가능) |
addInterceptors( ) | 애플리케이션 내에 인터셉터를 등록해 줍니다. 이 과정에서 excludePathPatterns( )를 이용하면, 메서드의 인자로 전달하는 주소(URI)와 경로(Path)는 인터셉터 호출에서 제외시킵니다. 여기서 해당 메서드는 resources의 모든 정적(static) 파일을 무시(ignore)하겠다는 의미로 사용됩니다. 반대의 경우로 addPathPatterns( )가 있습니다. excludePathPatterns( )가 주소와 경로를 인터셉터 호출에서 제외한다면, addPathPatterns( )는 인터셉터를 호출하는 주소와 경로를 추가하는 개념입니다. |
4. 인터셉터 테스트해 보기
게시글 리스트 페이지로 접근해보면, IDE 콘솔에 LoggerInterceptor에 구현한 preHandle( )과 postHandle( )에 작성한 로직대로 로그가 출력됩니다.
(이미지를 클릭하시면 확대해 보실 수 있습니다.)
마치며
사실, 인터셉터는 로그인, 권한, 인증과 같은 로직을 처리할 때 주로 사용된다는 말씀을 드렸었는데요. 우선은 로그를 출력하는 정도로 사용하고, 추후에 회원 기능이 구현되면 다시 한번 다루어 보도록 하겠습니다.
다음 글에서는 스프링에서 절대로 빠질 수 없는 AOP(Aspect Oriented Programming)를 애플리케이션에 적용해보고, 트랜잭션(Transaction)에 대해 공부하는 시간을 가져보겠습니다.
오늘도 방문해 주신 여러분께 진심으로 감사드립니다! 좋은 하루 보내세요 :)
댓글