본문 바로가기
Spring

스프링부트 - 인터셉터(Interceptor)

by khds 2022. 3. 6.

스프링 프로젝트를 진행하다 보면 controller에 접근전 공통적으로 처리해야 하는 로직이 있었을 것이다. controller로 이동하기 전에 로그인 정보를 확인한다든지, 보안토큰, 불필요한 파라미터나 파일 등을 전송 중인지 미리 확인하면 좋은데 이러한 상황에서 사용하는 것이 필터와 인터셉터이다. 
 
필터와 인터셉터는 비슷한 기능을 하지만 차이가 존재한다. 아래 사진을 봐보자. 
 

 
위 사진과 같이 스프링 프로젝트에서 요청이 와서 스프링 MVC를 사용하고 DispatcherServlet에 앞에서 처리를 하면 필터이고 뒤에서 처리하면 인터셉터이다.
 
아래는 좀 더 필터와 인터셉터의 구체적인 부분들이다.(출처: https://velog.io/@ansalstmd/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EB%8B%A4%EC%96%91%ED%95%9C-%EA%B8%B0%EB%8A%A5-5.-Spring-Boot-Filter%EC%99%80-Interceptor )
 

  • Filter란 Web Application에서 관리되는 영역으로써 Spring Boot Framework에서 Client로부터 오는 요청/응답에 대해서 최초/최종 단계의 위치에 존재하며, 이를 통해서 요청/응답의 정보를 변경하거나, Spring에 의해서 데이터가 변환되기 전의 순수한 Client의 요청/응답 값을 확인할 수 있다
  • 유일하게 ServletRequest, ServletResponse의 객체를 변환할 수 있다
  • 주로 Spring Framework에서는 request/response의 logging 용도로 활용하거나, 인증과 관련된 Logic들을 해당 Filter에서 처리한다
  • 이를 선/후 처리 함으로써, Service business logic과 분리시킨다

 

  • Interceptor란 Filter와 매우 유사한 형태로 존재 하지만, 차이점은 Spring Context에 등록
  • AOP와 유사한 기능을 제공할 수 있으며, 주로 인증 단계를 처리하거나, Logging를 하는 데 사용한다
  • 이를 선/후 처리 함으로써, Service business logic과 분리시킨다

 
그렇다면 이제 간단하게 프로젝트에 적용해 보겠다. 
 
먼저 interface HandlerInterceptor를 상속받아서 Interceptor를 구성한다. 
 

package calender.calender.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Log4j2
@Component
public class Interceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
        Object handler) throws Exception {
        String url = request.getRequestURI();
        log.info("request url : {}", url);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
        Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

 
 
-preHandler : 컨트롤러에 도착하기 전에 동작하는 메서드로 return값이 true이면 진행, false이면 멈춘다.
-postHandler : 컨트롤러에 도착하여 view가 랜더링 되기 전에 동작한다.
-afterCompletion: view가 정상적으로 랜더링 된 후에 마지막에 실행된다.
 
위에서는 preHandler안에 uri 로그를 출력하도록 하였다.
이제 작성한 인터셉터를 등록해야 하는데 아래와 같이 구현한다. 
 

package calender.calender.config;

import calender.calender.controller.Interceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@RequiredArgsConstructor
public class ServerConfig implements WebMvcConfigurer {

    private final Interceptor interceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).addPathPatterns();
    }
}

 
 
위와 같이 WebMvcConfigurer를 상속받아 addIntercepotrs를 통해 사용할 Interceptor를 등록하고. 패턴을 등록해준다.
위와 같이 작성한 후 실행하면 아래와 같다.
 

 
 
여기서 특정 주소에만 인터셉터가 동작하도록 할 수 있다. 
아래와 같이 작성한다. 
 

package calender.calender.config;

import calender.calender.controller.Interceptor;
import java.util.Arrays;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@RequiredArgsConstructor
public class ServerConfig implements WebMvcConfigurer {

    private final Interceptor interceptor;

    private static final List<String> URL_PATTERNS = Arrays.asList("/login", "/articles");  //인터셉터가 동작 해야 될 요청 주소 mapping 목록

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).addPathPatterns(URL_PATTERNS);
    }
}

 
 
그렇다면 /login, 과 /articles 에만 인터셉터가 동작할 것이다.

 

출처

https://congsong.tistory.com/24

스프링 부트(Spring Boot) - 인터셉터(Interceptor) 적용하기 [개발을 시작해봐요!]

이전 글에서는 프로젝트에 로그백(Logback)을 적용해서 SQL 쿼리 로그와 게시글의 정보를 테이블 형태로 출력하는 방법에 대해 알아보았습니다. 이번 글에서는 스프링에서 제공해주는 기능인 인터

congsong.tistory.com

https://velog.io/@ansalstmd/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EB%8B%A4%EC%96%91%ED%95%9C-%EA%B8%B0%EB%8A%A5-5.-Spring-Boot-Filter%EC%99%80-Interceptor

스프링부트 다양한 기능 5. Spring Boot Filter와 Interceptor

Filter란 Web Application에서 관리되는 영역으로써 Spring Boot Framework에서 Client로 부터 오는 요청/응답에 대해서 최초/최종 단계의 위치에 존재하며, 이를 통해서 요청/응답의 정보를 변경하거나, Spring

velog.io

https://myhappyman.tistory.com/199

SpringBoot - 인터셉터(Interceptor) 적용하기

스프링 프로젝트를 구성하여 개발하다보면 사용자가 로그인이 되었는지 접근이 가능한 사용자인지 보안토큰이나 불필요한 파라미터나 파일등을 전송중인지 여러가지를 앞단에서 먼저 체크하

myhappyman.tistory.com

https://linked2ev.github.io/spring/2019/09/15/Spring-5-%EC%84%9C%EB%B8%94%EB%A6%BF%EA%B3%BC-%EC%8A%A4%ED%94%84%EB%A7%81%EC%97%90%EC%84%9C-Context(%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8)%EB%9E%80/ 

[Spring] 서블릿과 스프링에서 Context(컨텍스트)란?

WebApplicationContext? ServletContext? SpringContext?은 뭐고, 서블릿과 스프링에서 말하는 Context(컨텍스트)란?

linked2ev.github.io

https://elfinlas.github.io/2017/12/28/SpringBootInterceptor/

Spring Boot에서 Interceptor 사용하기

인터셉터?Spring 또는 Spring Boot 프레임워크로 웹 어플리케이션을 개발하다 보면 아래와 같은 요구사항이 생기게 됩니다. 특정 url 진입 시 로그인이 된(인가된) 사용자가 접근을 해야 함 특정 url 진

elfinlas.github.io