본문 바로가기

Springboot

Filter, Intercepter

Filter는 Servlet이 제공하는 기능

Intercepter는 Spring이 제공하는 기능

 

게시글 작성 Controller에서 로그인 여부를 체크하는 Logic을 작성하면?

  1. 실제로는 수정, 삭제, 조회 등 모든 컨트롤러에 공통으로 로그인 여부를 체크해야 한다.
  2. 로그인 로직이 변경될 때 마다 로그인 여부를 체크하는 Logic 또한 변경될 가능성이 높다.
@Controller
@RequestMapping("/post")
public class PostController {

	@PostMapping("/")
	public void create(CreateRequestDto requestDto) {
		// 로그인 여부 확인 로직
	}

	@PutMapping("/")
	public void update(UpdateRequestDto requestDto) {
		// 로그인 여부 확인 로직
	}

	@DeleteMapping("/")
	public void delete(DeleteRequestDto requestDto) {
		// 로그인 여부 확인 로직
	}

}

여러가지 로직에서 공통으로 관심이 있는 부분(로그인 등)을 공통 관심사라고 한다

 

Servlet Filter

- 보안, 로깅, 인코딩, 인증/인가 등 다양한 작업을 처리하기 위해 사용

1. 공통 관심사 로직 -> 중앙 집중적인 로직 구현

2. HTTP 요청, 응답을 중간에 필터링할 수 있다

3. Filter Chain -> 여러 개의 필터가 순차적으로 적용될 수 있다

 - filterChain.doFilter(request, response); 다음 필터로 제어를 전달한다

4. doFilter -> 실제 필터링 작업을 수행하는 주요 메소드

 

Filter 적용후

  • Filter를 적용하면 Servlet이 호출되기 이전에 Filter를 항상 거치게된다.
  • 공통 관심사를 필터에만 적용하면 모든 요청 or 응답에 적용된다 .
  • Filter는 특정 URL Pattern에 적용할 수 있다.
    • ex) /* : 모든 요청 필터
  • Spring을 사용하는 경우 Servlet은 Dispatcher Servlet이다.

 

Filter Chain

  • Filter는 Chain 형식으로 구성된다.
  • Filter는 개발자가 자유롭게 추가할 수 있다.
  • Filter는 순서를 지정하여 추가할 수 있다.

 

Filter Interface

package jakarta.servlet;

import java.io.IOException;

public interface Filter {
	
	// default
	public default void init(FilterConfig filterConfig) {
	}

	public void doFilter(
		SevletRequest request, 
		SevletResponse response,
		FilterChain chain
	) throws IOException, ServletException;
	
	// default
	public default void destroy() {
	}

}

Filter Interface를 Implements하여 구현하고 등록하면 Servlet Container가 Filter를 Singleton 객체로 생성 및 관리한다

 

  • doFilter()
    • Client에서 요청이 올 때 마다 doFilter() 메서드가 호출된다.
      • doFilter() 내부에 필터 로직(공통 관심사 로직)을 구현하면 된다.
    • WAS에서 doFilter() 를 호출해주고 하나의 필터의 doFilter()가 통과된다면
    • Filter Chain에 따라서 순서대로 doFilter() 를 호출한다.
    • 더이상 doFilter() 를 호출할 Filter가 없으면 Servlet이 호출된다.
  • init()
    • Filter를 초기화하는 메서드이다.
    • Servlet Container가 생성될 때 호출된다.
    • default method이기 때문에 implements 후 구현하지 않아도 된다.
  • destroy()
    • 필터를 종료하는 메서드이다.
    • Servlet Container가 종료될 때 호출된다.
    • default method이기 때문에 implements 후 구현하지 않아도 된다.

 

Servlet Filter 구현

Filter 구현체

@Slf4j
public class CustomFilter implements Filter {

    @Override
    public void doFilter(
			ServletRequest request, 
			ServletResponse response, 
			FilterChain chain
		) throws IOException, ServletException {
	       
				// Filter에서 수행할 Logic
				HttpServletRequest httpRequest = (HttpServletRequest) request;
				String requestURI = httpRequest.getRequestURI();
				
				try {
					log.info("request URI={}", requestURI);
					
					chain.doFilter(request, response); // chain 이 없으면 Servlet을 바로 호출
				} catch(Exception e) {
					throw e;
				}
			
    }

}

servletRequest는 기능이 별로없고 대부분 기능이 많은 HttpServletRequest 를 사용한다

 

Filter 등록

@Configuration
public class WebConfig implements WebMvcConfigurer {
		
		@Bean
		public FilterRegistrationBean customFilter() {
				FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
				filterRegistrationBean.setFilter(new CustomFilter()); // Filter 등록
				filterRegistrationBean.setOrder(1); // Filter 순서 설정
				filterRegistrationBean.addUrlPatterns("/*"); // 전체 URL에 Filter 적용
				
				return filterRegistrationBean;
		}
}

 

Postman 호출

GET  http://localhost:8080/test

 

filterRegistrationBean.addUrlPatterns("/*")

 - 모든 Request는 Custom Filter를 항상 지나간다

 

정리

1. Filter를 사용하려면 Filter Interface를 Implements 하여 구현해야 한다.

2. HTTP 요청이 오면 doFilter()메서드가 호출된다

 -> ServletRequest는 기능이 별로 없으니 HttpServletRequest로 다운캐스팅 해야한다

 

chain.doFilter(request, response)

- (순서를 설정해둔)다음 필터가 있으면 Filter를 호출한다

- 다음 실행할 필터가 없으면 Servlet을 호출한다

- 해당 메서드를 호출하지 않으면 다음 단계로 진행되지 않는다

 - > 다음 필터나 Servlet을 호출하지 않는다

 

Filter를 등록하는 방법은 여러가지가 있다. SpringBoot의 경우

FilterRegistrationBean 사용

setFilter()

- > 등록할 필터를 파라미터로 전달하면 된다

 

setOrder()

  • Filter는 Chain 형태로 동작한다.
  • 즉, 실행될 Filter들의 순서가 필요하다.
  • 파라미터로 전달될 숫자에 따라 우선순위가 정해진다.
  • 숫자가 낮을수록 우선순위가 높다.

addUrlPatterns()

  • 필터를 적용할 URL 패턴을 지정한다.
  • 여러개 URL 패턴을 한번에 지정할 수 있다.
  • 규칙은 Servlet url-pattern과 같다.

코끼리를 냉장고에 넣는 방법 :: [서블릿/JSP] 서블릿 맵핑시 url-pattern 규칙 (tistory.com)

 

[서블릿/JSP] 서블릿 맵핑시 url-pattern 규칙

서블릿(Servlet) 맵핑시 url-pattern 규칙 구현한 서블릿은 특정 URL에 맵핑을 시켜주어야 합니다. 그래야 클라이언트에서 해당 URL로 요청시 해당 서블릿이 요청을 처리할 수 있기 때문입니다. URL 맵핑

dololak.tistory.com

 

 

'Springboot' 카테고리의 다른 글

AWS # Identity and Access Management  (0) 2024.07.05
QueryDSL, Auditing, Dynamic Insert/Update  (0) 2024.07.01
테이블 객체 만들기  (0) 2024.06.28
쿼리 파일 만들기 (QueryMapper)  (0) 2024.06.28
데이터베이스 연결(Driver)  (0) 2024.06.27