[Java] 서블릿 필터와 서블릿 필터체인
서블릿에 필터를 추가함으로서 서블릿 필터와 서블렛 필터의 등록 방법을 익히는 걸 목표로 한다.
서블릿 필터
서블릿 필터란 서블릿에 들어오기 전에, client로 부터 온 요청을 필터링 하는 것을 말한다.
-
인증(사용자 인증) 필터
-
로깅 및 감시(Audit) 필터
-
이미지 변환 및 데이터 압축 필터
-
암호화 필터
-
XML 컨텐츠를 변형하는 XSLT 필터
-
URL 및 기타 정보들을 캐싱하는 필터
와 같은 것들을 필터를 통해 구성하는데, 구현하기 위해서는 아래의 예시와 같이 Filter 인터페이스를 상속받아 구현한다.
서블릿 필터 1
package hello.servlet.basic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//@Order(1)
//@WebFilter(urlPatterns="/*")
public class FirstFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("첫번째 필터에 값 요청 드어옴");
chain.doFilter(request, response);
}
}
서블릿 필터 2
package hello.servlet.basic;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//@Order(0)
//@WebFilter(urlPatterns="/*")
public class SecondFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("두번째 필터에 값 요청 들어옴");
chain.doFilter(request, response);
}
}
이렇게 만들어진 두 개의 필터를 서블릿에 매핑하고 순서를 정하는 방법은 다음과 같다.
- WebFilter 어노테이션 사용
- Component 등록
- FilterConfig 등록
1. WebFilter
@WebFilter의 경우 @ServletComponentScan를 통해 빈으로 등록된다. @WebFilter(urlPatterns = “/filtered/*”) 같이 특정 url에 매핑하는 것이 가능하다. 이때 Filter의 순서를 지정하는 것은 불가능하다. 순서는 알파벳 순서로 작동한다.
따라서 순서를 정하기 위해선 2번 또는 3번의 방법을 사용해야한다.
2. Component + Order
구현한 필터를 Component를 통해 등록하고 Order를 통해 순서를 정할 수 있다. 이 경우에는 WebFilter와는 반대로 특정url에 매핑하는 것이 불가능하다.
3. FilterConfig
결국 순서와 url 매핑을 모두 하기 위해선 FilterConfig를 통해 설정해야한다.
package hello.servlet.basic;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ServletConfig {
@Bean
public FilterRegistrationBean<SecondFilter> secondFilter(){
FilterRegistrationBean<SecondFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new SecondFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(1);
registrationBean.setName("second-filter");
return registrationBean;
}
@Bean
public FilterRegistrationBean<FirstFilter> firstFilter(){
FilterRegistrationBean<FirstFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new FirstFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(3);
registrationBean.setName("first-filter");
return registrationBean;
}
}
다음과 같이 자신의 만든 필터를 제네릭으로 가지는 FilterRegistrationBean을 생성하여 순서, 매핑되는 url, 이름을 설정하면 필터를 커스텀 할 수 있다.