웹 개발 일기/Spring

Filter / Interceptor

핫반장 2021. 6. 17. 16:20

Filter란?

 

Filter는 웹 애플리케이션에서 관리되는 영역으로써 Spring Boot Framework에서 클라이언트로부터 오는 요청/응답에 대해서 최초/최종단계에 위치한다. Filter는 요청/응답의 정보를 변경하거나 데이터를 확인할 수 있다.

 

말 그대로 우리가 평소 알고 있는 필터의 역할을 한다고 생각하면 된다. 데이터가 알맞는지를 확인한다고 생각하자. 클라이언트가 보낸 정보를 필터로 걸러서 내용물을 확인하고 버리거나 원하는 것만 골라내서 요청을 보낸다.

 

이런 특징때문에 보안의 용도로 사용될 수 있는데, 해당 요청이 올바른지를 확인하여 요청을 승인하지 않는 등의 역할을 한다.

 

지금부터 작성할 내용은 요청이나 응답을 출력하는 필터를 적용한 것이다.

package com.example.filter.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
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);
      

        String url = httpServletRequest.getRequestURI();

        String reqContent = new String(httpServletRequest.getContentAsByteArray());
        log.info("request url : {}, request body : {}", url, reqContent);

        String resContent = new String(httpServletResponse.getContentAsByteArray());
        int httpStatus = httpServletResponse.getStatus();
        httpServletResponse.copyBodyToResponse();
        log.info("response status : {}, responseBody : {}", httpStatus, resContent);

    }
}

하나씩 살펴보도록 하자.

우선, GlobalFilter는 인터페이스 Filter를 상속받는다. 아래의 doFilter는 Filter의 메서드인데 request(요청), reponse(응답), chain, 이렇게 3가지의 파라미터를 포함한다. 여기서 chain은 여러 개의 필터가 이어진 것을 생각하면 된다.

 

httpServletRequest와 httpServletReponse는 각각 HTTP요청의 정보와 응답을 저장하는 객체이다.

chain.dofilter를 통해 정달된 reponse를 전달하여 그 결과를 클라이언트에 전달한다.

 

그 아래는 우리가 어떤 url에서 request를 받았는지, 또 그 request는 어떻게 생겼는지, response에 대한 상태는 어떤지, response는 어떻게 클라이언트에게 전달됐는지를 출력하는 코드이다.

 

정상적인 url을 통해 json형식의 데이터를 요청했다면

이런 식으로 정보가 출력된다.


Interceptor란?

 

Filter와 유사하지만 Filter와는 다르다.

보이는 바와 같이 Interceptor는 Spring Context내부에 존재한다. 그렇기 때문에 Filter와 Interceptor는 실행되는 시점이 다르다.