[spring] HandlerInterceptor란??

Minyoung kim·2024년 11월 26일
0

Spring

목록 보기
4/9

https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-servlet/handlermapping-interceptor.html

https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/interceptors.html

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


1. HandlerInterceptor란?

  • HandlerInterceptor는 Spring MVC에서 제공하는 인터페이스로, HTTP 요청을 처리하기 전후에 추가 로직을 실행할 수 있도록 지원합니다.
  • 컨트롤러 메서드 실행 전, 실행 후, 뷰 렌더링 후에 작업을 삽입할 수 있습니다.
  • 일반적으로 인증, 권한 검사, 로깅, 성능 측정과 같은 작업에 사용됩니다.

2. HandlerInterceptor의 주요 메서드

HandlerInterceptor는 세 가지 메서드를 제공합니다.

필요한 메서드만 선택적으로 구현하면 됩니다.

메서드역할
preHandle컨트롤러의 메서드가 실행되기 전에 실행. 요청을 가로채 필요한 전처리 작업 수행.
postHandle컨트롤러의 메서드가 실행된 후, 뷰가 렌더링되기 전에 실행. 컨트롤러가 반환한 데이터를 수정하거나 추가 작업 수행.
afterCompletion뷰 렌더링이 완료된 후 실행. 요청 처리 중 발생한 예외를 처리하거나 정리 작업 수행.

3. HandlerInterceptor 구현 방법

3.1 기본 구현

  1. 인터셉터 클래스 작성
    • HandlerInterceptor 인터페이스를 구현하거나 HandlerInterceptorAdapter를 상속받아 구현.

코드 예제

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Component
public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("PreHandle: 요청 처리 전");
        return true; // true면 다음 단계로 진행, false면 요청 처리 중단
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("PostHandle: 컨트롤러 실행 후, 뷰 렌더링 전");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("AfterCompletion: 뷰 렌더링 후");
    }
}

3.2 인터셉터 등록

인터셉터는 Spring MVC의 WebMvcConfigurer에 등록해야 동작합니다.

Spring Web MVC - WebMvcConfigurer

코드 예제

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 WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CustomInterceptor())
                .addPathPatterns("/api/**") // 적용할 경로
                .excludePathPatterns("/api/login"); // 제외할 경로
    }
}

4. HandlerInterceptor 동작 순서

  1. 클라이언트 요청preHandle 실행
  2. 컨트롤러 메서드 실행postHandle 실행
  3. 뷰 렌더링 완료afterCompletion 실행
sequenceDiagram
    participant Client as 클라이언트
    participant Interceptor as 인터셉터
    participant Controller as 컨트롤러
    participant View as 뷰

    Client->>Interceptor: 요청
    Interceptor->>Controller: preHandle 실행
    Controller->>Interceptor: 컨트롤러 실행 결과
    Interceptor->>View: postHandle 실행
    View->>Interceptor: 뷰 렌더링 완료
    Interceptor->>Client: afterCompletion 실행

5. HandlerInterceptor의 주요 사용 사례

5.1 인증 및 권한 검사

  • 사용자가 요청한 리소스에 접근할 수 있는 권한이 있는지 확인.
  • 예: 로그인 상태 확인.

코드 예제

@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authToken = request.getHeader("Authorization");
        if (authToken == null || !isValid(authToken)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
            return false; // 요청 중단
        }
        return true; // 요청 진행
    }

    private boolean isValid(String authToken) {
        // 토큰 검증 로직
        return "validToken".equals(authToken);
    }
}

5.2 로깅 및 성능 측정

  • 요청의 시작 시간과 종료 시간을 기록하여 처리 시간을 계산.
  • 요청/응답 로그를 기록.

코드 예제

@Component
public class LoggingInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        request.setAttribute("startTime", System.currentTimeMillis());
        logger.info("Request URL: " + request.getRequestURI());
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        long startTime = (long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        logger.info("Request URL: " + request.getRequestURI() + " completed in " + (endTime - startTime) + "ms");
    }
}

5.3 데이터 변환

  • 요청 데이터나 응답 데이터를 동적으로 수정.
  • 예: 헤더 추가, 요청 데이터를 가공.

코드 예제

@Component
public class HeaderModifierInterceptor implements HandlerInterceptor {

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        response.addHeader("X-Custom-Header", "CustomValue");
    }
}

6. HandlerInterceptor vs Filter

특징HandlerInterceptorFilter
Spring 의존성Spring MVC에서 제공, Spring 컨텍스트에 통합.Servlet 스펙에 정의, Spring과 독립적.
적용 범위컨트롤러(핸들러) 수준에서 동작.요청 전후 전체적인 작업(컨트롤러와 무관) 수행 가능.
사용 목적Spring MVC의 컨트롤러 전후 작업에 적합.보안, 요청/응답 처리 필터링에 적합.
데이터 접근컨트롤러의 핸들러 메서드와 관련된 작업 수행 가능.낮은 수준의 HTTP 요청/응답 처리 가능.

0개의 댓글