서블릿에 필터를 추가함으로서 서블릿 필터와 서블렛 필터의 등록 방법을 익히는 걸 목표로 한다.

서블릿 필터

서블릿 필터란 서블릿에 들어오기 전에, client로 부터 온 요청을 필터링 하는 것을 말한다.

  1. 인증(사용자 인증) 필터

  2. 로깅 및 감시(Audit) 필터

  3. 이미지 변환 및 데이터 압축 필터

  4. 암호화 필터

  5. XML 컨텐츠를 변형하는 XSLT 필터

  6. 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);
    }
}

이렇게 만들어진 두 개의 필터를 서블릿에 매핑하고 순서를 정하는 방법은 다음과 같다.

  1. WebFilter 어노테이션 사용
  2. Component 등록
  3. 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, 이름을 설정하면 필터를 커스텀 할 수 있다.