목차
1. 필터를 왜 쓰나요?
결론부터 말하면 공통부분을 따로 작성하여 중복 소스를 줄이고 소스 관리도 쉬워져 유지보수에 좋습니다.
Spring (자바) 개발을 하다 보면 공통적으로 처리해야 할 부분들이 많습니다.
예를 들으면 인코딩, CORS, XSS, LOG, 인증, 권한, 로그인(인증) 체크, 권한(인가) 체크 등과 같은 작업들이 있는데, 이러한 작업 코드를 소스마다 작성한다면 중복된 코드도 많아지고 프로젝트가 클 경우 부하를 줄 수도 있고 유지보수도 힘들게 됩니다.
필터는 이러한 공통부분을 따로 작성할 수 있게 도와주는 역할을 합니다.
인터셉터 외에도 인터셉터나 AOP가 있습니다.
2. 구조
3. 필터 특징
- 요청과 응답을 거른 뒤 정제하는 역할을 합니다.
- 필터는 DispatcherServlet 이전에 실행이 되는데 필터가 동작하도록 지정된 경로의 앞에서 요청 데이터를 확인 및 변경하거나, 응답 데이터에 대해서도 확인 및 변경하는 처리를 할 수가 있습니다.
- WebApplicationContext 기능으로 Spring Framework와 무관하게 동작하며, Spring 자원을 이용할 수 없습니다.
- 필터에서는 애플리케이션의 비즈니스 로직과 관계없는 작업을 주로 처리합니다.
- 주로 인코딩 변환 처리, XSS방어, CORS, Log 처리 등의 요청에 대한 처리로 사용합니다.
4. 필터 주요 메서드
init() - 필터 인스턴스 초기화 시 실행되는 메서드
doFilter() - 클라이언트의 요청/응답 처리 시 실행되는 메서드
destroy() - 필터 인스턴스가 제거될 때 실행되는 메서드
5. 필터 작성
스프링 부트의 필터 등록에는 두 가지가 있습니다. 맘에 드는 방식으로 필터를 등록하면 됩니다.
- 설정 파일에서 빈으로 등록
- @WebFilter 어노테이션 활용
먼저 Filter를 implements(상속) 하여 필터를 작성합니다.
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
init()
웹 컨테이너(톰캣)이 시작될 때 필터 최초 한 번 인스턴스 생성
doFilter()
클라이언트의 요청 시 전/후 처리
FilterChain을 통해 전달
public void destroy()
필터 인스턴스가 제거될 때 실행되는 메서드, 종료하는 기능
*/
@Slf4j
public class apiFilter implements Filter {
/*
- 필터 인스턴스 초기화
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("---필터 인스턴스 초기화---");
}
/*
- 전/후 처리
- Request, Response가 필터를 거칠 때 수행되는 메소드
- chain.doFilter() 기점으로 request, response 나눠집니다.
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String requestURI = req.getRequestURI();
log.info("---Request(" + requestURI + ") 필터---");
chain.doFilter(request, response);
log.info("---Response(" + requestURI + ") 필터---");
}
/*
- 필터 인스턴스 종료
*/
@Override
public void destroy() {
log.info("---필터 인스턴스 종료---");
}
}
5.1. 설정 파일 필터 빈 등록
import com.test.api.filter.apiFilter;
import com.test.api.interceptor.ApiInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
//Filter에 포함되는 URL 주소
private static final String[] INCLUDE_PATHS = {
"/test/*",
"/test2/*"
};
@Bean
public FilterRegistrationBean filterBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(new apiFilter());
registrationBean.setOrder(Integer.MIN_VALUE); //필터 여러개 적용 시 순번
// registrationBean.addUrlPatterns("/*"); //전체 URL 포함
// registrationBean.addUrlPatterns("/test/*"); //특정 URL 포함
// registrationBean.setUrlPatterns(Arrays.asList(INCLUDE_PATHS)); //여러 특정 URL 포함
registrationBean.setUrlPatterns(Arrays.asList("/test/*", "/test2/*"));
return registrationBean;
}
}
5.2. @WebFilter 어노테이션 등록
1. 필터 소스 위에 @WebFilter 어노테이션을 이용해 필터링할 패턴을 추가해줍니다.
@Slf4j
@WebFilter(urlPatterns = {"/test/*", "/test2/*"})
public class apiFilter implements Filter {
// (...) 생략
}
2. @SpringBootApplication 어노테이션을 가지고 있는 스프링 부트 실행 파일에 @ServletComponentScan 어노테이션을 추가합니다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan //추가
@SpringBootApplication
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
'Backend > Spring' 카테고리의 다른 글
[Spring Boot] REST API 예외처리(Response Json) (0) | 2021.12.01 |
---|---|
[Spring Boot] 윈도우 스프링 부트 Gradle 프로젝트 jar 빌드 방법 (0) | 2021.11.30 |
[Spring Boot] 스프링 부트 인터셉터 적용 (HandlerInterceptor) (0) | 2021.11.28 |
[Spring Boot] 스프링 부트 SSL 인증서 적용 (TLS, p12) (0) | 2021.11.26 |
[Spring] Lombok 자동 생성자 생성 (@AllArgsConstructor, @RequiredArgsConstructor) (0) | 2021.11.25 |