spring interceptor에서 http body를 추출할 수 있을까?

spring interceptor는 body를 추출할 수 없다.

  • 웹 어플리케이션을 다룰 때 보통 content-type은 application/x-www-form-urlencoded 혹은 application/json을 사용한다. 전자의 key와 value의 묶음인 query parameter는, http method인 get과 post에 관계 없이 컨트롤러와 스프링 인터셉터 등에서 손쉽게 활용 가능하다. 특히 인터셉터에서 파라미터에 대한 로깅을 할 때 효과적으로 사용 가능하다.
  • 좀 더 욕심을 내자. 후자인 json을 로그로 남기고 싶었다. 여러 시도를 했지만 결과적으로 실패하였다.
  • 실패한 이유와 해결책은 다음 블로그에 잘 정리되어 있다. https://stuffdrawers.tistory.com/9
  • 해당 내용을 정리하면 대략 아래와 같다.

filter와 interceptor 사이에 inputStream이 고갈된다.

  • body가 interceptor로 넘어오기 전, 스프링은 body 데이터가 있는 inputStream 를 사용하고 close() 한다.
  • inputStream을 interceptor에서 사용하기 위해서는 filter에서 해당 데이터를 복제해야 한다. 복제한 데이터를 HttpServletRequest에 넘기고, interceptor는 복제한 객체를 꺼내서 사용한다.
  • filter에서 interceptor로 inputStream의 데이터를 전달할 때 사용하는 데이터 타입이 HttpServletRequestWrapper 이다.

스프링은 filter에서 http를 읽을 수 있는 기능을 제공한다.

  • (2023.02.16) 바디를 로깅할 수 있으나 다소 복잡한 세팅을 해야 한다고 정리하였다. 최근 기술 블로그를 보며 관련한 필터를 스프링이 제공함을 확인했다. 특별한 세팅 없이 필터에 대한 빈 설정 하나로 바디를 비롯한 http 메시지 전반에 대한 로깅이 가능하다.
  • CommonsRequestLoggingFilter에 대한 빈을 등록하고, 해당 필터의 로깅 수준을 DEBUG로 설정한다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CommonsRequestLoggingFilter; 

@Configuration
public class MyFilter {

    @Bean
    public CommonsRequestLoggingFilter requestLoggingFilter() {
        CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
        loggingFilter.setIncludeClientInfo(true);
        loggingFilter.setIncludeHeaders(true);
        loggingFilter.setIncludeQueryString(true);
        loggingFilter.setIncludePayload(true);
        loggingFilter.setMaxPayloadLength(64000);
        return loggingFilter;
    }
}
  • application.yml
logging:
  level:
    org:
      springframework:
        web:
          filter:
            CommonsRequestLoggingFilter: DEBUG
  • 출처
  • https://www.baeldung.com/spring-http-logging
  • https://stackoverflow.com/questions/33744875/spring-boot-how-to-log-all-requests-and-responses-with-exceptions-in-single-pl