SpringBoot: 인터셉터(interceptor)의 동작원리

2023. 8. 13. 14:19·Spring/Spring 기초 지식
반응형
 
 

스프링 부트에서 사용되는 Interceptor의 동작원리를 알아보자

 

1. 스프링부트에서 인터셉터란?

스프링부트에서의 인터셉터

  • 스프링부트에서 인터셉터는 웹 애플리케이션에서 요청과 응답을 처리하는 중간 단계에서 사용된다. 인터셉터는 특정 URI 패턴에 대한 요청을 가로채어, 컨트롤러가 처리하기 전후에 추가적인 작업을 할 수 있게 해 준다. 이를 통해, 로그인 체크, 권한 검증, 로깅 등과 같은 작업을 효율적으로 처리할 수 있다.

 

인터셉터의 동작 과정

  1. 클라이언트로부터 들어오는 요청(HttpRequest)을 가로챈다.
  2. 가로챈 요청에 대해 원하는 처리(예: 로그인 체크, 권한 체크 등)를 수행한다.
  3. 처리가 끝난 후, 요청을 원래의 목적지인 컨트롤러로 전달한다.
  4. 컨트롤러가 응답(HttpResponse)을 반환하면, 이 응답 역시 가로챌 수 있다.
  5. 가로챈 응답에 대해 원하는 처리(예: 응답 로깅 등)를 수행한 후, 응답을 클라이언트로 전달한다.

2. interceptor 사용예시 (xml 사용)

지금부터 스프링부트에서 Interceptor를 사용하는 예시를 확인해 보자
이 예시에서는 인터셉터를 사용하여 로그인 처리를 하는 방법을 보여준다.


먼저, 인터셉터를 설정하는 방법부터 살펴보자.

  • 스프링 설정 파일에서 인터셉터를 설정할 수 있다. 아래의 설정은 모든 요청을 가로채서 com.victolee.interceptor 패키지에 있는 MyInterceptor 객체를 실행하겠다는 의미다.
<!-- Interceptors -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <bean class="com.victolee.interceptor.MyInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

 

다음으로, 인터셉터를 구현하는 방법을 살펴보자.

  • 인터셉터를 구현하기 위해서는 HandlerInterceptor 인터페이스를 구현하거나 HandlerInterceptorAdapter 클래스를 상속받아야 한다.
public class MyInterceptor implements HandlerInterceptor {

    // controller로 보내기 전에 처리하는 인터셉터
    // 반환이 false라면 controller로 요청을 안함
    // 매개변수 Object는 핸들러 정보를 의미한다. ( RequestMapping , DefaultServletHandler ) 
    @Override
    public boolean preHandle(
        HttpServletRequest request, HttpServletResponse response,
        Object obj) throws Exception {
    
        System.out.println("MyInterCeptor - preHandle");
        return false;
    }

    // controller의 handler가 끝나면 처리됨
    @Override
    public void postHandle(
        HttpServletRequest request, HttpServletResponse response,
        Object obj, ModelAndView mav)
        throws Exception {
    }

    // view까지 처리가 끝난 후에 처리됨
    @Override
    public void afterCompletion(
        HttpServletRequest request, HttpServletResponse response,
        Object obj, Exception e)
        throws Exception {
    }
}
  • 위의 코드에서 preHandle 메서드는 컨트롤러가 호출되기 전에 실행되며, postHandle 메서드는 컨트롤러가 실행된 후에 호출되고, afterCompletion 메서드는 뷰에서 최종 결과가 생성하는 일을 포함한 모든 일이 완료 되었을 때 실행된다.

마지막으로, 로그인 처리를 위한 인터셉터를 구현하는 예제를 살펴보자

  • 아래의 코드에서는 AuthLoginInterceptor가 HandlerInterceptorAdapter를 상속받아 preHandle 메서드를 오버라이딩 하여 로그인 처리를 수행한다.
  • 클라이언트가 로그인 버튼을 눌렀을 때 email과 pwd를 전달한다고 가정하면, getParameter 메서드로 데이터를 가져올 수 있고 UserVO를 Service 계층에 전달하여 해당 유저가 존재하는지 확인한다.
public class AuthLoginInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private UserService userService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
        Object handler) throws Exception {
    
        String email = request.getParameter("email");
        String pwd = request.getParameter("pwd");
    
        UserVO vo = new UserVO();
        vo.setEmail(email);
        vo.setPwd(pwd);
        userService.getUser(vo);
    
        return false;
    }
}
이렇게 인터셉터를 활용하면, 로그인 처리와 같은 반복적인 작업을 컨트롤러에서 분리하여 코드의 중복을 줄이고 관리를 용이하게 할 수 있다.

 

3. interceptor 사용예시 (@Configuration 어노테이션 사용)

이 예시에서는 @Configuration 어노테이션을 적용시킨 후 로그를 출력하는 간단한 인터셉터를 만들어보겠다.

 

먼저, HandlerInterceptor 인터페이스를 구현하는 LoggerInterceptor 클래스를 만들어보자

  • 아래의 LoggerInterceptor 클래스는 HandlerInterceptor 인터페이스를 구현하고 있으며, preHandle 메서드와 postHandle 메서드를 오버라이드하고 있다. 
  • preHandle 메서드는 컨트롤러가 호출되기 전에 실행되며, postHandle 메서드는 컨트롤러가 실행된 후에 호출된다. 이 예시에서는 각 메서드에서 로그를 출력하도록 구현하였다.
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);
    }
}

 

다음으로, WebMvcConfigurer 인터페이스를 구현하는 WebMvcConfig 클래스를 만들어보자. 이 클래스에서 인터셉터를 등록한다.

  • 아래의 WebMvcConfig 클래스는 WebMvcConfigurer 인터페이스를 구현하고 있으며, addInterceptors 메서드를 오버라이드하고 있다. addInterceptors 메서드에서는 LoggerInterceptor를 등록하고, 특정 패턴의 경로를 인터셉터의 적용에서 제외하고 있다.
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/**");
    }
}

 

📌 마무리

이렇게 설정하면, 인터셉터가 정상적으로 동작하게 된다. 이 예시에서는 모든 요청에 대해 요청 URI를 로그로 출력하게 된다. 참고로, 이 예시는 스프링 부트 2.x 버전을 기준으로 작성되었다. 스프링 부트 3에서도 동일하게 적용할 수 있다.

 

 

필터가 인터셉터와 다른점을 알아보자👇🏻👇🏻

 

Spring: 필터(Filter)가 인터셉터(Interceptor)와 다른점

이번 포스트에서는 Spring Filter에 대해서 알아보도록 하자 1. Spring에서 Filter의 개념 필터의 정의 필터는 웹 애플리케이션에서 클라이언트의 요청과 서버의 응답을 가로채는 재사용 가능한 코드

curiousjinan.tistory.com

 

반응형

'Spring > Spring 기초 지식' 카테고리의 다른 글

Spring Boot: @ControllerAdvice/@RestControllerAdvice로 예외처리하기  (6) 2023.10.23
Spring: Maven과 Gradle의 차이  (0) 2023.08.17
Spring MVC의 Model, ModelAndView, ModelMap 비교  (0) 2023.08.13
스프링에서의 데이터베이스 접근 방법: DAO, Mapper, 그리고 @Mapper 어노테이션 사용법  (0) 2023.08.09
스프링에서 데이터 전달의 핵심: VO와 DTO의 이해 및 활용  (0) 2023.08.09
'Spring/Spring 기초 지식' 카테고리의 다른 글
  • Spring Boot: @ControllerAdvice/@RestControllerAdvice로 예외처리하기
  • Spring: Maven과 Gradle의 차이
  • Spring MVC의 Model, ModelAndView, ModelMap 비교
  • 스프링에서의 데이터베이스 접근 방법: DAO, Mapper, 그리고 @Mapper 어노테이션 사용법
Stark97
Stark97
문의사항 또는 커피챗 요청은 링크드인 메신저를 보내주세요! : https://www.linkedin.com/in/writedev/
  • Stark97
    오늘도 개발중입니다
    Stark97
  • 전체
    오늘
    어제
    • 분류 전체보기 (242) N
      • 개발지식 (20)
        • 스레드(Thread) (8)
        • WEB, DB, GIT (3)
        • 디자인패턴 (8)
      • JAVA (21)
      • Spring (88)
        • Spring 기초 지식 (35)
        • Spring 설정 (6)
        • JPA (7)
        • Spring Security (17)
        • Spring에서 Java 활용하기 (8)
        • 테스트 코드 (15)
      • 아키텍처 (6) N
      • MSA (14)
      • DDD (8) N
      • gRPC (9)
      • Apache Kafka (18)
      • DevOps (23)
        • nGrinder (4)
        • Docker (1)
        • k8s (1)
        • 테라폼(Terraform) (12)
      • AWS (32)
        • ECS, ECR (14)
        • EC2 (2)
        • CodePipeline, CICD (8)
        • SNS, SQS (5)
        • RDS (2)
      • notion&obsidian (3)
      • 동아리 (0)
  • 링크

    • notion기록
    • 깃허브
    • 링크드인
  • hELLO· Designed By정상우.v4.10.0
Stark97
SpringBoot: 인터셉터(interceptor)의 동작원리
상단으로

티스토리툴바