[Spring] Filter vs Interceptor 는 뭐가 다를까?

코찔찔이💻·2024년 4월 27일
0

상황 : 장바구니, 멤버십 전용 메뉴 등을 이용할 때, 로그인을 해야 접근할 수 있는 경우들이 있다. 이와 같이, 로그인이 지속적으로 필요한 기능을 구현할 때, 해당 로직에 로그인 기능을 반복해서 추가해야만 한다.

이렇게 공통적인 처리를 대신 해주는 객체를 구현해준다면, 반복적인 코드 작성 뿐만 아니라, 재사용성과 유연한 결합까지 모두 챙길 수 있다.

서블릿 필터와 스프링 인터셉터는 HttpServletRequest, HttpServletResponse를 제공해주기 때문에, url 정보나 http header를 직접 조작할 수 있다.

서블릿 필터

Servlet API 2.3부터 등장해, Dispatcher Servlet의 요청이 전달되기 전 후, 실행을 낚아 채어 부가작업을 처리하는 객체

  • init, doFilter, destroy 메서드를 오버라이딩 할 수 있고, doFilter는 필수적으로 오버라이딩해 주어야 한다.
  • init은 톰캣 실행 전, filter가 생성될 시, 딱 한번만 실행되는 default 메서드이다.
  • doFilter는 요청이 들어올 때마다 실행이 되기 때문에, 직접적인 인증이나 부가적인 작업은 직접 작성해주어야 한다.
  • destroy는 톰캣 종료 전 filter가 소멸될 시, 딱 한번만 실행되는 default 메서드이다.
  • doFilter 메서드를 실행할 때, 반드시 FilChain 객체를 매개변수로 받은 chain 객체의 doFilter 를 호출해야 다음 filter가 동작할 수 있다.

@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain){
HttpServletRequest servletRequest = (HttpServletRequest) reqeust;
try{
	validateToken(servletRequest);// 인증 로직
	chain.doFilter(request,response);
}catch(Exception e){
	HttpServletResponse servletResponse = (HttpServletResponse) response;
	servletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());

	}
}

Filter를 적용하는 방법

1) @Component 애노테이션 적용

  • 모든 URL에 적용되기 때문에, 특정 URL에서만 실행될 경우에는 좋지 않은 방법이다.

2)@WebFilter & @ServletComponentScan 애노테이션 적용

  • Filter class에 @WebFilter 어노테이션을 붙인다.
  • Application class에 @ServletComponentScan을 붙인다.
  • 해당 방법으로 각각 다른 URL에 적용할 수 있다.
  • 스프링 컨테이너가 아닌, 서블릿 컨테이너에 등록되기 때문에 @Order 애노테이션을 사용할 수 없다.

3)FilterRegistrationBean 객체로 메서드 호출하기

  • FilterRegistrationBean 객체 생성
  • setFilter 지정
  • setOrder 지정
  • addUrlPatterns(url) 지정
  • FilterRegistrationBean 객체 반환
  • 순서와 URL 지정 가능

스프링 인터셉터


Handler 조회 → 적절한 HandlerAdapter 가져옴 → preHandle → HandlerAdapter를 통해 Handler 실행 → postHandle → view 처리 → afterCompletion

디스패처 서블릿이 컨트롤러 호출 전/후로 실행을 낚아채어 부가적인 작업을 수행하도록 하는 것

  • prehandle : handler가 실행되기 전에 실행되는 메서드
  • postHandle : handler가 실행된 이후에 실행되는 메서드
  • afterCompletion : 비즈니스 로직에서 예외가 발생했다면, 해당 메서드에서 처리가 가능하다. 리소스 정리 때도 사용할 수 있다.

인터셉터 등록 방법

1) WebMvcConfigurer 인터페이스를 구현한 클래스 내부에서 addInterceptor 메서드를 오버라이딩

2) addPathPatterns(”/***”)로 모든 URI 요청에 대해서 인터셉터 적용

3)excludePathPatterns(”/***”)로 인터셉터를 적용하지 않을 URI를 작성

Interceptor 동작 방식

1) DispatcherServlet.doService 메서드 호출

2) doDispatch 메서드 호출 →getHandler로 알맞은 handler를 가져옴(핸들러 조회)

3)getHandlerAdapter → handler에 맞는 handlerAdapter를 찾아온다.

4)preHandle 메서드를 실행하기 위해, HandlerExecutionChain의 applyHandler 메서드 호출

5) 직접 구현한 Interceptor의 preHandle 메서드가 실행

6) HandlerAdapter를 통해 Handler가 실행

7) 비즈니스 로직이 모두 실행된 후, postHandle을 실행할 수 있는 applyPostHandle 메서드가 호출 된 후 반복문을 돈다.

8) preHandle과는 역순으로 실행

9) 직접 구현한 Interceptor의 postHandle이 실행

10) DispatcherServlet의 processDispatchResult 메서드가 호출

11) render 메서드 호출 → view 관련 로직 처리

12) afterCompletion 메서드 실행

13) 직접 구현한 Interceptor의 afterCompletion이 실행

필터 vs 인터셉터

필터인터셉터
자바 표준 스펙스프링이 제공하는 기술
필터 실행을 위해 개발자가 명시적으로 작성해야 한다.다음 인터셉터를 실행하기 위해 개발자가 신경써야 할 부분이 없다
ServletRequest, ServletResponse를 필터 체이닝 중간에 새로운 객체로 바꿀 수 있다.ServletRequest, ServletResponse를 인터셉터 체이닝 중간에 새로운 객체로 바꿀 수 없다.
필터 예외 발생 시, @ControllerAdvice에서 처리하지 못한다.인터셉터 예외 발생 시, @ControllerAdvice에서 처리할 수 있다.
profile
버티면 다 되는거야.

0개의 댓글