그림 그리는 개발자
  • 스프링부트 Filter 실습
    2022년 01월 30일 21시 46분 16초에 업로드 된 글입니다.
    작성자: 루루개발자

    안녕하세요. 이번에는 스프링부트의 Filter 를

    직접 구현해보는 시간을 가져보고자 합니다.

     

    스프링부트에서 Filter 는 여러개가 등록될 수 있다고 합니다.

    여러개가 등록될 수 있다면 Filter 의 순서도 컨트롤 할 수 있어야 할 것 같은데,

    알아보니 setOrder 메서드를 이용해 필터의 순서를 지정해줄 수 있다고 합니다.

     

    그럼 실습용 Filter 를 3개 정도 만들어서 로그를 찍어봄으로써

    정말 순서대로 호출이 되는지, 한번 알아보겠습니다.

     

    우선 다음과 같이 3개의 패키지 및 클래스를 생성합니다.

     

    필터에 해당하는 코드는 다음과 같습니다.

     

    filters/TestFilter1.java (첫번째 필터)

    package com.example.springbootsampleproject.filters;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class TestFilter1 implements Filter {
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            this.logger.info("TestFilter1 진입!");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }

     

    filters/TestFilter2.java (두번째 필터)

    package com.example.springbootsampleproject.filters;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class TestFilter2 implements Filter {
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            this.logger.info("TestFilter2 진입!");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }

     

    filters/TestFilter3.java (세번째 필터)

    package com.example.springbootsampleproject.filters;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class TestFilter3 implements Filter {
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            this.logger.info("TestFilter3 진입!");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }

     

    필터를 다 만들었으면, 이제 이 필터를 스프링부트에 등록해주어야 합니다.

    그러기 위해선 Configuration 어노테이션을 달아줄 클래스를 하나 생성해야 합니다.

     

    configurations/FilterConfiguration.java

    package com.example.springbootsampleproject.configurations;
    
    import com.example.springbootsampleproject.filters.TestFilter1;
    import com.example.springbootsampleproject.filters.TestFilter2;
    import com.example.springbootsampleproject.filters.TestFilter3;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class FilterConfiguration {
        @Bean
        public FilterRegistrationBean<TestFilter1> testFilter1() {
            FilterRegistrationBean<TestFilter1> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setFilter(new TestFilter1());
            // registrationBean.addUrlPatterns("/user/*"); // 특정 URL 에 맵핑되는 경우에만 필터가 적용되게 할수도 있음
            registrationBean.setOrder(1); // 필터의 순서를 지정
            // registrationBean.setName("TestFilter1"); // 필터의 이름을 지정
            return registrationBean;
        }
    
        @Bean
        public FilterRegistrationBean<TestFilter2> testFilter2() {
            FilterRegistrationBean<TestFilter2> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setFilter(new TestFilter2());
            // registrationBean.addUrlPatterns("/user/*"); // 특정 URL 에 맵핑되는 경우에만 필터가 적용되게 할수도 있음
            registrationBean.setOrder(2); // 필터의 순서를 지정
            // registrationBean.setName("TestFilter2"); // 필터의 이름을 지정
            return registrationBean;
        }
    
        @Bean
        public FilterRegistrationBean<TestFilter3> testFilter3() {
            FilterRegistrationBean<TestFilter3> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setFilter(new TestFilter3());
            // registrationBean.addUrlPatterns("/user/*"); // 특정 URL 에 맵핑되는 경우에만 필터가 적용되게 할수도 있음
            registrationBean.setOrder(3); // 필터의 순서를 지정
            // registrationBean.setName("TestFilter3"); // 필터의 이름을 지정
            return registrationBean;
        }
    }

     

    FilterConfiguration 이란 이름을 가진 클래스를 생성하고

    해당 클래스에 Configuration 어노테이션을 달아줍니다.

     

    그리고 FilterRegistrationBean 을 통해 아까 생성한 필터를 등록해주는

    메서드를 각 필터마다 생성해주고 해당 메서드에는 Bean 어노테이션을 달아줍니다.

     

    여기까지 해주면, 스프링부트가 구동될 때 필터가 등록되어 필터가 구동되게 됩니다.

     

    그리고 3개의 필터를 거친 뒤 정상적으로 컨트롤러까지 도달하는지도 테스트해보기 위해

    테스트용 컨트롤러도 다음과 같이 만들어 줍니다.

     

    controllers/TestController.java

    package com.example.springbootsampleproject.contollers;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    @RequestMapping("/test")
    public class TestController {
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @GetMapping("")
        public @ResponseBody String index() {
            this.logger.info("TestController 진입!");
            return "This is Test Page!";
        }
    }

     

    테스트 준비가 모두 완료되었습니다. 스프링부트를 구동해서 8080포트로 LISTEN 중임을 확인하고,

    POSTMAN 을 통해 다음과 같이 Request 를 날려보았습니다.

     

     

    테스트 결과 등록한 3개의 필터가 원하는 순서대로 호출되고,

    컨트롤러까지 무사히 도달하는 것을 확인해 볼 수 있었습니다.

    댓글