오늘 또 하나 배웠다...
사실 전 부터 배웠는데 오늘 좀 생각을 정리했다...? 여러 번 듣고 여러 번 책에서 본 내용인데도 제대로 개념을 이해 못했던 것이지....
전 부터 buffer를 한 번 사용해서 빈다 <- 라는 말을 자주 들었다. 이게 무슨 의미인지 이번에 코드를 짜보고 null이 찍히는 것을 보며 무엇인지 확실히 알게 되었다.
[ 순서 ]
클라이언트단에서 요청이 들어온다.
-> spring Controller에 도달하기 전, filter에서 buffer를 한번 사용하고 빈다.-> Controller에 도달하는 response body가 없다-> Error : Required request body is missing
이럴 때 wrapper 를 사용하는데, 내가 계속 사용했던 것은 ContentCachingResponseWrapper,
ContentCachingRequestWrapper class이다.
당연하게 ContentCachingRequestWrapper 를 이용했는데 디버깅을 돌려보면 자꾸 캐싱이 되지 않았다.
알고보니 이것은 dofilter를 하고 사용을 하고 났을 때.. 그 뒤에서 또 사용할 수 있게 만들어 주는 클래스라고 했다.
그러니까 dofilter를 하고 또 사용할 수 있게 cashing이 되는 것이다.
그런데 나는 이미 inputstream을 한번하고 dofilter를 했으니 cashing되지 않았던 것이다.
public class LoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//custom해서 만든 request wrapper class
CachingRequestWrapper cachingRequestWrapper = new CachingRequestWrapper((HttpServletRequest) request);
ContentCachingResponseWrapper cachingResponseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);
// request body 읽어오기
InputStream contentInputStream = cachingRequestWrapper.getInputStream();
String requestBody = StreamUtils.copyToString(contentInputStream, StandardCharsets.UTF_8);
Map<String,String> map = new ObjectMapper().readValue(requestBody, Map.class);
//method, uri 등 필요한 값 가져올 때
cachingRequestWrapper.getMethod(),
cachingRequestWrapper.getRequestURI()
// doFilter
chain.doFilter(cachingRequestWrapper, cachingResponseWrapper);
cachingResponseWrapper.copyBodyToResponse();
}
}
이렇게 request wrapper class를 만들어주고 사용하면 doFilter이전에 버퍼가 비워져도 상관없다!
'TIL' 카테고리의 다른 글
[TIL] Spring boot @Deprecated 어노테이션 (0) | 2023.06.27 |
---|---|
[TIL] git flow - hotfix branch 를 main에 merge한 이후에? (0) | 2023.06.22 |
[TIL] HttpServletRequest 에서 request 값을 GET, POST에서 사용하기 (0) | 2023.06.19 |
[TIL] logback 설정 어렵다 (1) | 2023.06.18 |
[TIL] pinpoint를 통해 들어오는 요청들을 확인해보았다. (0) | 2023.06.02 |