Interceptor

초코칩·2024년 5월 14일
0

spring

목록 보기
11/16
post-thumbnail

Intercetor

인터셉터(Interceptor)는 스프링 프레임워크에서 제공하는 기능으로, 웹 애플리케이션에서 HTTP 요청과 응답을 가로채서 처리하는 데 사용된다. 이는 요청이 컨트롤러에 도달하기 전이나 응답이 클라이언트에게 반환되기 전에 특정 작업을 수행할 수 있게 해준다.

Spring의 interceptor는 HandlerInterceptor 인터페이스를 구현하여 생성할 수 있다. HandlerInterceptor 인터페이스를 사용하면 다음의 세 시점의 공통 기능을 넣을 수 있다.

  • preHandle(): 클라이언트의 요청을 컨트롤러에 전달하기 전에 필요한 작업을 수행한다. 예를 들어, 사용자 인증 및 권한 확인, 로깅, 요청 데이터 검증 등을 수행할 수 있다.
  • postHandle(): 컨트롤러가 요청을 처리한 후, 뷰가 렌더링되기 전에 필요한 작업을 수행한다. 예를 들어, 응답 데이터 변환, 로깅, 특정 헤더 추가 등을 수행할 수 있다.
  • afterCompletion(): 뷰가 렌더링된 후, 모든 처리가 완료된 후에 필요한 작업을 수행한다. 주로 리소스 정리나 예외 처리를 위해 사용된다.

세 가지 기능에 대해 알아보자.

preHandle()

  • 역할: 클라이언트의 요청이 컨트롤러에 전달되기 전에 호출된다.
  • 용도: 요청을 가로채고, 요청을 처리하기 전에 필요한 작업을 수행한다. 예를 들어, 사용자 인증 및 권한 확인, 로깅, 요청 데이터 검증 등을 수행할 수 있다.
  • 반환 값: boolean 값을 반환한다. true를 반환하면 요청 처리가 계속 진행되어 다음 인터셉터 또는 컨트롤러가 호출된다. false를 반환하면 요청 처리가 중단되며, false를 반환할 경우 직접 응답을 작성하여 클라이언트에게 반환해야 한다.
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 인증 및 권한 확인 로직
    if (userIsNotAuthenticated) {
        response.sendRedirect("/login");
        return false;
    }
    return true;
}

postHandle()

  • 역할: 컨트롤러가 요청을 처리한 후, 뷰가 렌더링되기 전에 호출된다.
  • 용도: 컨트롤러가 처리한 결과에 추가적인 처리를 할 때 사용된다. 예를 들어, 모델에 추가적인 데이터를 넣거나 응답에 헤더를 추가하는 등의 작업을 수행할 수 있다.
  • 참고: 이 메서드는 컨트롤러가 정상적으로 실행된 후에만 호출된다. 예외가 발생하면 호출되지 않는다.

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    // 추가적인 모델 데이터 설정
    if (modelAndView != null) {
        modelAndView.addObject("additionalData", "value");
    }
}

afterCompletion()

  • 역할: 모든 요청 처리가 완료된 후, 즉 뷰가 렌더링된 후에 호출된다.
  • 용도: 요청 처리가 끝난 후 리소스를 정리하거나, 예외가 발생했을 때 후처리를 하는 데 사용된다. 예를 들어, 열려 있는 데이터베이스 연결을 닫거나, 요청 처리 중에 발생한 예외를 로깅하는 등의 작업을 수행할 수 있다.
  • 참고: 요청 처리가 정상적으로 완료되었든 예외가 발생했든 항상 호출된다.
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    // 리소스 정리 또는 예외 처리
    if (ex != null) {
        logger.error("Error occurred: ", ex);
    }
    // 예를 들어, 열려 있는 파일이나 데이터베이스 연결 닫기
}

HandlerInterceptor와 컨트롤러의 실행 흐름을 그림으로 보면 아래 그림과 같이 정리 할 수 있다.

Interceptor 등록

HandlerInterceptor를 통해 Interceptor를 생성했다면, Interceptor를 어디에 적용하지 설정해야 한다.

인터셉터를 설정하려면 WebMvcConfigurer 인터페이스를 구현하는 설정 클래스를 작성한다.

@Configuration
public class WebConfig implements WebMvcConfigurer {

	private final MyInterceptor myInterceptor;
    
    public WebMvcConfiguration(MyInterceptor myInterceptor) {
        this.myInterceptor = myInterceptor;
    }
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**") // 모든 경로에 인터셉터 적용
                .excludePathPatterns("/login", "/signup", "/css/**", "/js/**") // 특정 경로 제외
                .order(1); // 인터셉터 순서 지정

        registry.addInterceptor(new AnotherInterceptor())
                .addPathPatterns("/admin/**") // 관리자 경로에만 적용
                .order(2); // 순서 지정
    }
}

작성된 Configuration 클래스에 인터셉터를 등록할 수 있다. 인터셉터 등록 시, 여러 옵션들을 설정할 수 있는데 이에 대해 알아보자.

옵션

  • addPathPatterns(String... patterns): 인터셉터가 적용될 URL 패턴을 지정한다. 여러 패턴을 지정할 수 있으며, /**는 모든 요청에 대해 인터셉터를 적용하는 것을 의미한다.

  • excludePathPatterns(String... patterns): 인터셉터 적용에서 제외할 URL 패턴을 지정합니다. 로그인, 회원가입 등 특정 경로를 제외할 때 유용하다.

  • order: 인터셉터의 순서를 지정할 수 있다. 기본적으로는 인터셉터가 등록된 순서대로 적용되지만, 명시적으로 순서를 지정할 수도 있다.

이렇게 설정하면 각 요청이 지정된 패턴과 순서에 따라 인터셉터를 거치게 된다. 이를 통해 요청 전후에 필요한 로직을 유연하게 추가하고 관리할 수 있다.

profile
초코칩처럼 달콤한 코드를 짜자

0개의 댓글

관련 채용 정보