오답노트

[Spring] Filter 본문

Java/Spring

[Spring] Filter

권멋져 2023. 7. 14. 11:29

Filter

웹 어플리케이션에서 관리되는 영역으로써 Spring Boot Framework에서 Client로 부터 오는 요청/응답에 대해서 최초/최종 단계의 위치에 존재하며, 이를 통해서 요청/응답의 정보를 변경하거나, Spring에 의해서 데이터가 변환되기 전의 순수한 Client의 요청/응답 값을 확인 할 수 있다.

 

유일하게 ServletRequest, ServletResponse의 객체를 변환 할  수 있다.

 

주로 스프링에서는 요청과.응답의 logging 으로 활용하거나, 인증과 관련된 logic들을 해당 filter에서 처리한다.

 

이를 선/후 처리 함으로써, Service business logic과 분리 시킨다.

@SpringBootApplication
@ServletComponentScan
public class FilterApplication {

    public static void main(String[] args) {
        SpringApplication.run(FilterApplication.class, args);
    }

}

메인 클래스에  ServletComponentScan Annotation을 등록한다.

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/api/user/*")
public class GlobalFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //전처리
        ContentCachingRequestWrapper httpServletRequest = new ContentCachingRequestWrapper((HttpServletRequest)request);
        ContentCachingResponseWrapper httpServletResponse = new ContentCachingResponseWrapper((HttpServletResponse)response);

        chain.doFilter(httpServletRequest, httpServletResponse); // 내용이 들어감

        //후처리
        //req
        String reqContent = new String(httpServletRequest.getContentAsByteArray());
        String url = httpServletRequest.getRequestURI();
        log.info("response status : {}, responseBody : {}",url, reqContent);

        String resContent = new String(httpServletResponse.getContentAsByteArray());
        int httpStatus = httpServletResponse.getStatus();

        httpServletResponse.copyBodyToResponse();

        log.info("response status : {}, responseBody : {}",httpStatus, resContent);

    }
}

WebFilter Annotation으로 어떤 url에서 필터를 적용할지 지정한다.

 

Filter 인터페이스를 상속한 클래스를 만들고 doFilter를 Override한다.

 

요청과 응답에서 읽은 데이터는 모두 Stream이기 때문에 Filter에서 한 번 읽으면 다른 곳에서는 사용할 수 없다.

그래서 ContentCachingRequestWrapper와 ContentCachingResponseWrapper를 활용하면 Filter에서 읽더라도 다른 곳에서 읽을 수 있다.

 

chain.doFilter 메소드를 호출하면 요청과 응답에 있는 데이터를 가져온다.

 

 

'Java > Spring' 카테고리의 다른 글

[Spring] 비동기 처리 (Async)  (0) 2023.07.14
[Spring] Interceptor  (0) 2023.07.14
[Spring] Exception과 Validation  (0) 2023.07.14
[Spring] Exception  (0) 2023.07.14
[Spring] Validation  (0) 2023.07.13