![[Spring] 서블릿 필터와 스프링 인터셉터 비교하기!](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqNoS3%2FbtsIWfzYzbv%2FhmAK74KUYgkqWhgImKRAA0%2Fimg.png)
일반적인 웹 페이지는 로그인한 사용자와 로그인하지 않은 사용자를 구분하여 역할에 맞는 기능을 제공해야한다.
먼저, 프론트 화면처리로 로그인하지 않은 사용자에게는 상품관리
라는 버튼을 숨겨서 기능을 제공하지 않을 수 있지만, URL경로를 직접 호출하게 된다면 프론트 처리만으로는 서비스에 제한을 둘 수 없다.
이런 로그인 여부확인은 회원가입, 정보수정, 삭제 등등 많은 서비스에서 사용되는데 여러 곳에서 공통으로 사용되는 로직을 웹에서는 스프링인터셉터를 사용하여 웹과 관련된 공통 관심사를 처리할 수 있다.
서블릿 필터
- 필터는 서블릿 스펙의 일부로 스프링 MVC와는 독립적으로 동작하며 모든 요청에 대해 동작할 수 있다.
javax.servlet.Filter
인터페이스를 사용한다.- 모든 HTTP요청에 대해 공통적으로 처리해야 할 로직이 있을 때 사용(인코딩설정, CORS, 로깅 등)
- 스프링 MVC이외의 서블릿이나 JSP와 같은 다른 기술과 함께 사용될 때 사용
- 서블릿 컨테이너 레벨에서 요청을 가로채고 처리해야할 때 사용
==서블릿이 지원하는 필터==
필터의 정상흐름
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러
필터의 제한흐름
HTTP 요청 -> WAS -> 필터 -> 서블릿 호출X
예를들어 필터에서 로그인되지않은 사용자라고 판단하면 서블릿을 호출하지않고 필터에서 옳바르지않은 요청에대한 응답을 처리할 수 있다.
==스프링 부트에서 필터 등록==
스프링에서 제공하는 FilterRegistrationBean
을 사용하면 스프링 빈으로 필터를 편리하게 등록할 수 있다.
setFilter(new ExampleFilter())
: 등록할 필터를 지정setOrder(1)
: 필터가 여러개 있을 때 동작 순서를 지정한다.addUrlPatterns("/*")
: 필터를 적용할 URL패턴을 지정한다.
참고로 @ServletComponentScan
, @WebFilter
와 같은 어노테이션으로 필터를 등록할 수 있지만 이 경우에는 필터 순서 조절이 불가능하기때문에 FilterRegistrationBean
을 사용하는 것을 권장한다.
==예제==
@Configuration
public class FilterConfiguration {
@Bean
public FilterRegistrationBean<MyFilter> testFilter() {
FilterRegistrationBean<MyFilter> filter = new FilterRegistrationBean<>();
filter.setFilter(new MyFilter());
filter.addUrlPatterns("/test");
return filter;
}
}
FilterRegistrationBean
을 통하여 필터를 등록한다.
public class MyFilter implements Filter {
private int number = 0;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
number++;
System.out.println("필터 시작 " + number);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
number++;
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestURI = request.getRequestURI();
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setStatus(205);
System.out.println("요청 URI: " + requestURI);
System.out.println("doFilter " + number);
filterChain.doFilter(request, servletResponse);
}
@Override
public void destroy() {
System.out.println("필터 종료 " + number);
}
}
아무의미없는 필터를 구현한 클래스로 필터에 사용 시점마다 number
변수에 +1을 해주며 doFilter
에서 요청에 대한 URL을 출력하고 다음 필터 또는 컨트롤러를 호출하도록 한다.
필터 시작 1
...SPRING BOOT 실행로그 생략...
요청 URI: /test
doFilter 2
컨트롤러 1
스프링 부트애플리케이션이 올라가기전에 필터가 먼저 시작되고, 컨트롤러를 호출하기전에 필터가 사용되는 것을 실행결과를 통해 확인할 수 있다.
스프링 인터셉터
스프링 인터셉터도 서블릿 필터와 같이 웹과 관련된 공통 관심 사항을 효과적으로 해결하는 기술이다.
인터셉터는 스프링 MVC가 제공하는 기술로 몇 가지 차이점이있다.
==스프링 인터셉터 흐름==
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
==스프링 인터셉터 제한 흐름==
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러 호출 X
스프링 인터셉터는 서블릿 필터보다 편리하고 더 정교한 다양한 기능을 지원한다.
인터셉터를 사용하기위해서는 HanlderInterceptor
를 구현하면 된다.
preHandle()
postHandle()
afterCompletion()
서블릿 필터의 경우에는doFilter()
메서드 하나만 제공되기때문에 컨트롤러가 호출되기 전에 사용되는 필터만 가능했지만,
인터셉터를 사용한다면 컨트롤러 호출 전, 호출 후, 요청완료 이후와 같이 세분화된 상태로 사용할 수 있다.
==스프링 인터셉터 예외==
preHandle
은 컨트롤러 호출 전에 호출되기때문에 예외와 관계없다.postHandle
은 컨트롤러에서 예외가 발생하면 호출되지 않는다.afterCompletion
은 항상 호출되기때문에 어떤 예외가 발생됐는지 확인할 수 있다.
==스프링 인터셉터 등록==WebMvcConfigurer
를 구현한 설정 클래스를 통해 인터셉터를 편리하게 등록할 수 있다.
InterceptorRegistry
: 인터셉터를 등록하는 클래스addInterceptor(new ExampleInterceptor())
: 인터셉터를 등록addPathPatterns("/**)
: 인터셉터를 적용할 URL패턴을 지정한다.excludePathPatterns()
: 인터셉터에서 제외할 패턴을 지정한다.
참고
PathPattern에대한 공식문서
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/ web/util/pattern/PathPattern.html
'Framework > Spring' 카테고리의 다른 글
[Spring] - API예외 처리를 이해하기위한 기본 개념! (2) | 2024.09.06 |
---|---|
[Spring] 쉬우면서 정확하게 익혀보는 필터와 인터셉터의 예외처리 흐름과 예외 페이지 응답 (0) | 2024.09.04 |
[Spring] JdbcTemplate (0) | 2024.06.16 |
Spring - 메시지 기능으로 HTML하드코딩 제거하기 (0) | 2024.04.23 |
Spring MVC - @RequestMapping (0) | 2024.04.16 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!