본문 바로가기

Spring/Spring

[Spring] 스프링 인터셉터

반응형

스프링 인터셉터는 서블릿 필터와 비슷하게 웹과 관련된 공통 괌심 사항을 해결하는 기술이다.

우선 스프링 인터셉터의 흐름에 대해 알아보자.

HTTP 요청 - WAS - 필터 - 서블릿 - 인터셉터 - 컨트롤러

필터는 서블릿 이전에 적용되었지만 인터셉터는 디스패처 서블릿과 컨트롤러 사이에 적용된다.

이 순서를 쉽게 외우는 방법 중 하나는 인터셉터는 스프링이 제공하기 때문에 스프링 mvc의 시작인 디스패처 서블릿 이후에 인터셉터가 적용된다고 생각하면 이해가 될 것이다.

 

인터셉터 제한

HTTP 요청 - WAS - 필터 - 서블릿 - 스프링 인터셉터 - 컨트롤러
HTTP 요청 - WAS - 필터 - 서블릿 - 스프링 인터셉터 - X

정상적인 요청이라면 HTTP 요청부터 컨트롤러까지의 흐름을 타지만 로그인을 안 한 사용자처럼 비정상적인 요청이 들어온다면 인터셉터가 컨트롤러를 호출하지 않는다. (intercepter 뜻처럼 호출을 가로채는 역할이다.)

인터셉터 체인

HTTP 요청 - WAS - 필터 - 서블릿 - 인터셉터1 - 인터셉터2 - 컨트롤러

필터가 필터 체인처럼 적용될 수 있듯이 인터셉터도 체인처럼 적용이 가능하다.

 


 

인터셉터 인터페이스

public interface HandlerInterceptor {

	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return true;
	}

	
	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}

}

필터와 비슷한 구조이다. 인터셉터는 컨트롤러 (핸들러) 직전에 사용하기 때문에

preHandle - 핸들러 이전에 적용되는 메서드로 boolean이기 때문에 true면 계속 진행하고 false면 이후 단계를 호출하지 안흔다.

postHandle - 핸들러 이후에 적용되는 메서드로 

afterCompletion - 뷰가 렌더링 된 이후에 호출, preHandle이 true건 false건 상관없이 호출된다.

 

인터셉터를 적용한 간단한 코드를 통해 알아보자.

public class ExIntercepter implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        HttpSession session = request.getSession();

        if (session == null) {
            response.sendRedirect("다시 보낼 URL");
            return false;
        }
        return true;
    }
}

위 코드에서 3가지 단계 중 preHandle만 있어서 의아할 수 있지만 필터에서 필터 역할을 하는 doFilter 메서드가 주로 개발되는 것처럼 검증 로직이 들어가는 preHandle만 구현해보았다. 

session이 null이면 다시 redirect를 시키고 false를 리턴했다. 이것은 위에 설명한 것처럼 이후의 컨트롤러를 호출하지 않고 여기서 끝내겠다는 뜻이다. 그리고 만약 session이 있어서 null이 아니라면 true를 반환하게 되는데 이것은 이후의 단계를 계속 진행하는 것을 나타낸다.

 

인터셉터 등록

   @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogIntercepter())
                .order(1)
                .addPathPatterns("/**")
                .excludePathPatterns("/css/**", "/*.ico", "/error");

        registry.addInterceptor(new LoginCheckIntercepter())
                .order(2)
                .addPathPatterns("/**")
                .excludePathPatterns("/", "/members/add", "/login", "/logout", "/css/**", "/*.ico", "/error");
    }

필터와 마찬가지로 인터셉터도 지정한 Config 파일에 등록해야 쓸 수 있다. (필터는 Bean으로 등록하지만 인터셉터는 오버라이드 해준다.)

order - 인터셉터의 우선순위를 정한다.

addPathPatterns - 인터셉터를 적용할 URL 패턴을 추가한다.

excludePathPatterns - 인터셉터를 적용하지 않은 URL 패턴을 추가한다.

 

필터와 인터셉터를 둘 다 알아야 하지만 인터셉터가 더 개발하기 수월하므로 꼭 필터를 적용해야 하는 상황이 아니라면 인터셉터를 사용하자.

반응형

'Spring > Spring' 카테고리의 다른 글

[Spring] 서블릿 예외 처리 - 필터  (0) 2024.12.05
[Spring] 서블릿 예외 처리 -1  (0) 2024.12.04
[Spring] 서블릿 필터  (2) 2024.12.02
[Spring] BindingFailure  (0) 2024.11.26
[Spring] @ServletComponentScan  (0) 2024.11.19